home *** CD-ROM | disk | FTP | other *** search
/ Nebula 1 / Nebula One.iso / Graphics / Multimedia / Movie3.0 / Source / xanim / xanim_avi.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-06-02  |  75.2 KB  |  2,283 lines

  1.  
  2. /*
  3.  * xanim_avi.c
  4.  *
  5.  * Copyright (C) 1993,1994 by Mark Podlipec. 
  6.  * All rights reserved.
  7.  *
  8.  * This software may be freely copied, modified and redistributed without
  9.  * fee for non-commerical purposes provided that this copyright notice is
  10.  * preserved intact on all copies and modified copies.
  11.  * 
  12.  * There is no warranty or other guarantee of fitness of this software.
  13.  * It is provided solely "as is". The author(s) disclaim(s) all
  14.  * responsibility and liability with respect to this software's usage
  15.  * or its effect upon hardware or computer systems.
  16.  *
  17.  */
  18. /* The following copyright applies to all Ultimotion segments of the code:
  19.  *
  20.  * "Copyright International Business Machines Corporation 1994, All rights
  21.  *  reserved. This product uses Ultimotion(tm) IBM video technology."
  22.  *
  23.  */
  24.  
  25. /*******************************
  26.  * Revision
  27.  *
  28.  * 16Aug94 +video chunks of 0 size now properly used as NOP's with timing info.
  29.  *
  30.  ********************************/
  31.  
  32. #include "xanim_avi.h" 
  33.  
  34. LONG Is_AVI_File();
  35. ULONG AVI_Read_File();
  36. void AVI_Print_ID();
  37. AVI_FRAME *AVI_Add_Frame();
  38. void AVI_Free_Frame_List();
  39. ULONG RIFF_Read_AVIH();
  40. ULONG RIFF_Read_STRH();
  41. ULONG RIFF_Read_VIDS();
  42. ULONG RIFF_Read_AUDS();
  43. void AVI_Audio_Type();
  44. ULONG AVI_Get_Color();
  45. void AVI_Get_RGBColor();
  46.  
  47. /* CODEC ROUTINES */
  48. ULONG AVI_Decode_RLE8();
  49. ULONG AVI_Decode_CRAM();
  50. ULONG AVI_Decode_CRAM16();
  51. ULONG AVI_Decode_RGB();
  52. ULONG AVI_Decode_ULTI();
  53. extern ULONG QT_Decode_CVID();
  54. extern void QT_Gen_YUV_Tabs();
  55. ULONG AVI_Get_Ulti_Color();
  56. void AVI_Get_Ulti_rgbColor();
  57. void AVI_ULTI_Gen_YUV();
  58. void AVI_ULTI_LTC();
  59. void AVI_Ulti_Gen_LTC();
  60. ULONG AVI_Ulti_Check();
  61.  
  62. void CMAP_Cache_Clear();
  63. void CMAP_Cache_Init();
  64.  
  65. XA_ACTION *ACT_Get_Action();
  66. XA_CHDR *ACT_Get_CMAP();
  67. XA_CHDR *CMAP_Create_332();
  68. XA_CHDR *CMAP_Create_422();
  69. XA_CHDR *CMAP_Create_Gray();
  70. void ACT_Add_CHDR_To_Action();
  71. void ACT_Setup_Mapped();
  72. void ACT_Get_CCMAP();
  73. XA_CHDR *CMAP_Create_CHDR_From_True();
  74. ULONG CMAP_Find_Closest();
  75. UBYTE *UTIL_RGB_To_FS_Map();
  76. UBYTE *UTIL_RGB_To_Map();
  77.  
  78. ULONG UTIL_Get_MSB_Long();
  79. ULONG UTIL_Get_LSB_Long();
  80. ULONG UTIL_Get_LSB_Short();
  81.  
  82. /** AVI SOUND STUFF ****/
  83. ULONG avi_audio_attempt;
  84. ULONG avi_audio_type;
  85. ULONG avi_audio_freq;
  86. ULONG avi_audio_chans;
  87. ULONG avi_audio_bps;
  88. ULONG avi_audio_end;
  89. AUDS_HDR auds_hdr;
  90. #ifdef POD_AUDIO_BETA
  91. void XA_Add_Sound();
  92. #endif
  93.  
  94.  
  95. ULONG avi_cmap_flag;
  96. ULONG avi_cmap_cnt;
  97. ULONG avi_cmap_frame_num;
  98. ULONG avi_cf2_rmap[256],avi_cf2_gmap[256],avi_cf2_bmap[256];
  99.  
  100. static LONG ulti_Cr[16],ulti_Cb[16],ulti_CrCb[256];
  101. UBYTE *avi_ulti_tab = 0;
  102.  
  103. #define AVI_MAX_COLORS  256
  104. ColorReg avi_cmap[AVI_MAX_COLORS];
  105. XA_CHDR *avi_chdr;
  106.  
  107. AVI_HDR avi_hdr;
  108. AVI_STREAM_HDR strh_hdr;
  109. VIDS_HDR vids_hdr;
  110.  
  111. ULONG avi_use_index_flag;
  112. ULONG avi_frame_cnt;
  113. ULONG avi_imagex,avi_imagey,avi_imagec;
  114. ULONG avi_depth,avi_compression;
  115. ULONG avi_time,avi_timelo;
  116. UBYTE *avi_pic;
  117. ULONG avi_pic_size;
  118. ULONG avi_max_fsize;
  119.  
  120. AVI_FRAME *avi_frame_start,*avi_frame_cur;
  121.  
  122. AVI_FRAME *AVI_Add_Frame(time,timelo,act)
  123. ULONG time,timelo;
  124. XA_ACTION *act;
  125. {
  126.   AVI_FRAME *fframe;
  127.  
  128.   fframe = (AVI_FRAME *) malloc(sizeof(AVI_FRAME));
  129.   if (fframe == 0) TheEnd1("AVI_Add_Frame: malloc err");
  130.  
  131.   fframe->time   = time;
  132.   fframe->timelo = timelo;
  133.   fframe->act = act;
  134.   fframe->next = 0;
  135.  
  136.   if (avi_frame_start == 0) avi_frame_start = fframe;
  137.   else avi_frame_cur->next = fframe;
  138.  
  139.   avi_frame_cur = fframe;
  140.   avi_frame_cnt++;
  141.   return(fframe);
  142. }
  143.  
  144. void AVI_Free_Frame_List(fframes)
  145. AVI_FRAME *fframes;
  146. {
  147.   AVI_FRAME *ftmp;
  148.   while(fframes != 0)
  149.   {
  150.     ftmp = fframes;
  151.     fframes = fframes->next;
  152.     FREE(ftmp,0xA000);
  153.   }
  154. }
  155.  
  156. /*
  157.  *
  158.  */
  159. LONG Is_AVI_File(filename)
  160. char *filename;
  161. {
  162.   FILE *fin;
  163.   ULONG data;
  164.  
  165.   if ( (fin=fopen(filename,XA_OPEN_MODE)) == 0) return(XA_NOFILE);
  166.   data = UTIL_Get_MSB_Long(fin);  /* read past size */
  167.   fclose(fin);
  168.   if ( data == RIFF_RIFF ) return(TRUE);
  169.   return(FALSE);
  170. }
  171.  
  172. ULONG AVI_Read_File(fname,anim_hdr)
  173. char *fname;
  174. XA_ANIM_HDR *anim_hdr;
  175. {
  176.   FILE *fin;
  177.   LONG i,ret;
  178.   XA_ACTION *act;
  179.  
  180.   if ( (fin=fopen(fname,XA_OPEN_MODE)) == 0)
  181.   {
  182.     fprintf(stderr,"can't open AVI File %s for reading\n",fname);
  183.     return(FALSE);
  184.   }
  185.  
  186.   avi_cmap_flag = 0;
  187.   avi_cmap_cnt = 0;
  188.   avi_pic = 0;
  189.   avi_pic_size = 0;
  190.   avi_chdr = 0;
  191.   avi_frame_cnt = 0;
  192.   avi_frame_start = 0;
  193.   avi_frame_cur = 0;
  194.   avi_time    = 100; /* default */
  195.   avi_timelo    = 0;   /* default */
  196.   avi_max_fsize = 0;
  197.   avi_imagex    = avi_imagey = avi_imagec = 0;
  198.   avi_compression = 0;
  199.   avi_use_index_flag = 0;
  200.   avi_audio_attempt = FALSE;
  201.  
  202.   while( !feof(fin) )
  203.   {
  204.     ULONG d,ck_id,ck_size;
  205.  
  206.     ck_id = UTIL_Get_MSB_Long(fin);
  207.     ck_size = UTIL_Get_LSB_Long(fin);
  208. DEBUG_LEVEL2 
  209. {
  210.   fprintf(stderr,"AVI cid ");
  211.   AVI_Print_ID(stderr,ck_id);
  212.   fprintf(stderr,"  cksize %08lx\n",ck_size);
  213. }
  214.     switch(ck_id)
  215.     {
  216.     case RIFF_RIFF:
  217.         d = UTIL_Get_MSB_Long(fin);
  218.         DEBUG_LEVEL2 
  219.         {
  220.             fprintf(stderr,"  RIFF form type ");
  221.             AVI_Print_ID(stderr,d);
  222.             fprintf(stderr,"\n");
  223.         }
  224.                 break;
  225.     case RIFF_LIST:
  226.         d = UTIL_Get_MSB_Long(fin);
  227.         DEBUG_LEVEL2 
  228.         {
  229.             fprintf(stderr,"  List type ");
  230.             AVI_Print_ID(stderr,d);
  231.             fprintf(stderr,"\n");
  232.         }
  233.         break;
  234.  
  235.     case RIFF_avih:
  236.         DEBUG_LEVEL2 fprintf(stderr,"  AVI_HDR:\n");
  237.                 if (RIFF_Read_AVIH(fin,ck_size,&avi_hdr)==FALSE) return(FALSE);
  238.                 break;
  239.  
  240.     case RIFF_strh:
  241.         DEBUG_LEVEL2 fprintf(stderr,"  STRH HDR:\n");
  242.                 if (RIFF_Read_STRH(fin,ck_size,&strh_hdr)==FALSE) return(FALSE);
  243.                 break;
  244.  
  245.     case RIFF_strf:
  246.         DEBUG_LEVEL2 fprintf(stderr,"  STRF HDR:\n");
  247.                 switch(strh_hdr.fcc_type)
  248.                 {
  249.                  case RIFF_vids:
  250.            if (RIFF_Read_VIDS(fin,ck_size,&vids_hdr)==FALSE)
  251.                 return(FALSE);
  252.            break;
  253.                  case RIFF_auds:
  254.            { ULONG ret = RIFF_Read_AUDS(fin,ck_size,&auds_hdr);
  255. #ifdef POD_AUDIO_BETA
  256.              if (xa_audio_enable==TRUE)
  257.              {
  258.             if (ret==FALSE)
  259.             {
  260.               fprintf(stderr,"  AVI Audio Type Unsupported\n");
  261.               avi_audio_attempt = FALSE;
  262.             }
  263.             else avi_audio_attempt = TRUE;
  264.              }
  265. #endif
  266.            }
  267.            break;
  268.                  default:
  269.            fprintf(stderr,"unknown fcc_type at strf");
  270.            return(FALSE);
  271.            break;
  272.                 }
  273.                 break;
  274.  
  275.         case RIFF_00iv:
  276.         case RIFF_00db:
  277.         case RIFF_00vc:
  278.         case RIFF_00dc:
  279.         case RIFF_00dx:
  280.         case RIFF_00xx:
  281.       {
  282.         ACT_DLTA_HDR *dlta_hdr;
  283.         ULONG d;
  284.  
  285.         act = ACT_Get_Action(anim_hdr,ACT_DELTA);
  286.         if (ck_size & 0x01) ck_size++;
  287.         if (ck_size == 0)  /* NOP wait frame */
  288.         {
  289.           act->type = ACT_NOP;
  290.           act->data = 0;
  291.           act->chdr = 0;
  292.           AVI_Add_Frame( avi_time, avi_timelo, act);
  293.           break;
  294.         }
  295.  
  296.         if (xa_file_flag==TRUE)
  297.         {
  298.           dlta_hdr = (ACT_DLTA_HDR *) malloc(sizeof(ACT_DLTA_HDR));
  299.           if (dlta_hdr == 0) TheEnd1("AVI 00dc: malloc failed");
  300.           act->data = (UBYTE *)dlta_hdr;
  301.           dlta_hdr->flags = ACT_SNGL_BUF;
  302.           dlta_hdr->fpos  = ftell(fin);
  303.           dlta_hdr->fsize = ck_size;
  304.           fseek(fin,ck_size,1); /* move past this chunk */
  305.           if (ck_size > avi_max_fsize) avi_max_fsize = ck_size;
  306.         }
  307.         else
  308.         {
  309.           d = ck_size + (sizeof(ACT_DLTA_HDR));
  310.           dlta_hdr = (ACT_DLTA_HDR *) malloc( d );
  311.           if (dlta_hdr == 0) TheEnd1("AVI 00dc: malloc failed");
  312.           act->data = (UBYTE *)dlta_hdr;
  313.           dlta_hdr->flags = ACT_SNGL_BUF | DLTA_DATA;
  314.           dlta_hdr->fpos = 0; dlta_hdr->fsize = ck_size;
  315.           ret = fread( dlta_hdr->data, ck_size, 1, fin);
  316.           if (ret != 1) 
  317.         {fprintf(stderr,"AVI 00dc: read failed\n"); return(FALSE);}
  318.         }
  319.  
  320.         AVI_Add_Frame( avi_time, avi_timelo, act);
  321.         dlta_hdr->xpos = dlta_hdr->ypos = 0;
  322.         dlta_hdr->xsize = avi_imagex;
  323.         dlta_hdr->ysize = avi_imagey;
  324.         dlta_hdr->special = 0;
  325.         dlta_hdr->extra = 0;
  326.         switch(avi_compression)
  327.         {
  328.           case RIFF_RLE8:
  329.         if (avi_depth == 8) dlta_hdr->delta = AVI_Decode_RLE8;
  330.         else goto AVI_UNSUPPORTED;
  331.         break;
  332.           case RIFF_MSVC:
  333.           case RIFF_CRAM:
  334.         if (avi_depth == 8) dlta_hdr->delta = AVI_Decode_CRAM;
  335.         else if (avi_depth ==16) dlta_hdr->delta = AVI_Decode_CRAM16;
  336.         else goto AVI_UNSUPPORTED;
  337.         break;
  338.           case RIFF_ULTI:
  339.         if (avi_depth == 16) dlta_hdr->delta = AVI_Decode_ULTI;
  340.         else goto AVI_UNSUPPORTED;
  341.         break;
  342.           case RIFF_RGB:
  343.         if (avi_depth == 8) dlta_hdr->delta = AVI_Decode_RGB;
  344.         else goto AVI_UNSUPPORTED;
  345.         break;
  346.           case RIFF_CVID:
  347.         if (avi_depth == 24) dlta_hdr->delta = QT_Decode_CVID;
  348.         else goto AVI_UNSUPPORTED;
  349.         break;
  350.           default:
  351.         AVI_UNSUPPORTED:
  352.         fprintf(stderr,"AVI: unsupported comp ");
  353.         AVI_Print_ID(stderr,avi_compression);
  354.         fprintf(stderr," with depth %ld\n",avi_depth);
  355.         act->type = ACT_NOP;
  356.         return(FALSE);
  357.         break;
  358.         }
  359.         if ( (xa_buffer_flag == TRUE) && (act->type != ACT_NOP) )
  360.         {
  361.           ULONG xpos,ypos,xsize,ysize,dlta_flag;
  362.  
  363.           if ( (cmap_true_map_flag==FALSE) || (avi_depth <= 8) )
  364.           {
  365.         ULONG map_flag = 
  366.             (x11_display_type & XA_X11_TRUE)?(TRUE):(FALSE);
  367.             dlta_flag = dlta_hdr->delta(avi_pic,dlta_hdr->data,
  368.             dlta_hdr->fsize,0,avi_chdr->map,map_flag,
  369.             avi_imagex,avi_imagey,8,&xpos,&ypos,&xsize,&ysize,0,0);
  370.         if (!(dlta_flag & ACT_DLTA_MAPD)) map_flag = FALSE;
  371.         xsize -= xpos; ysize -= ypos;
  372.             FREE(dlta_hdr,0xA001); act->data = 0;
  373.             if (dlta_flag & ACT_DLTA_NOP) act->type = ACT_NOP;
  374.             else ACT_Setup_Mapped(act,avi_pic,avi_chdr,xpos,ypos,xsize,
  375.             ysize,avi_imagex,avi_imagey,FALSE,0, FALSE,TRUE,map_flag);
  376.             ACT_Add_CHDR_To_Action(act,avi_chdr);
  377.           } 
  378.           else /* decode as RGB triplets and then convert to mapped image */
  379.           {
  380.         UBYTE *tpic;
  381.         dlta_flag = dlta_hdr->delta(avi_pic,dlta_hdr->data,
  382.             dlta_hdr->fsize,0,0,FALSE,
  383.             avi_imagex,avi_imagey,8,&xpos,&ypos,&xsize,&ysize,1,0);
  384.         xpos = ypos = 0; xsize = avi_imagex; ysize = avi_imagey;
  385.         FREE(dlta_hdr,0xA002); act->data = 0; dlta_hdr = 0;
  386.         if (dlta_flag & ACT_DLTA_NOP) act->type = ACT_NOP;
  387.         else
  388.         {
  389.           if (    (cmap_true_to_all == TRUE)
  390.               || ((cmap_true_to_1st == TRUE) && (avi_chdr == 0) )
  391.              )  avi_chdr = CMAP_Create_CHDR_From_True(avi_pic,8,8,8,
  392.                 avi_imagex,avi_imagey,avi_cmap,&avi_imagec);
  393.           else if ( (cmap_true_to_332 == TRUE) && (avi_chdr == 0) )
  394.             avi_chdr = CMAP_Create_332(avi_cmap,&avi_imagec);
  395.           else if ( (cmap_true_to_gray == TRUE) && (avi_chdr == 0) )
  396.             avi_chdr = CMAP_Create_Gray(avi_cmap,&avi_imagec);
  397.          
  398.           if (cmap_dither_type == CMAP_DITHER_FLOYD)
  399.             tpic = UTIL_RGB_To_FS_Map(0,avi_pic,avi_chdr,
  400.                         avi_imagex,avi_imagey,FALSE);
  401.           else tpic = UTIL_RGB_To_Map(0,avi_pic,avi_chdr,
  402.                         avi_imagex,avi_imagey,FALSE);
  403.           ACT_Setup_Mapped(act,tpic,avi_chdr,xpos,ypos,xsize,ysize,
  404.             avi_imagex,avi_imagey,FALSE,0,TRUE,TRUE,FALSE);
  405.           ACT_Add_CHDR_To_Action(act,avi_chdr);
  406.         } /* end of not NOP */
  407.           } /* end of true_map */
  408.         } /* end of buffer */
  409.         else /* not buffered */ACT_Add_CHDR_To_Action(act,avi_chdr);
  410.       {
  411.         /* Also make sure not TRUE, is 332 and special case file_flag */
  412.         if ( (cmap_color_func != 0)
  413.             && (avi_depth > 8) && (!(x11_display_type & XA_X11_TRUE)) )
  414.         {
  415.         if (avi_cmap_flag==0)
  416.         {
  417.             ULONG xpos,ypos,xsize,ysize,dlta_flag,psize;
  418.             UBYTE *cbuf,*data;
  419.  
  420.           psize = avi_imagex * avi_imagey;
  421.           cbuf = (UBYTE *) malloc(3 * psize);
  422.           if (cbuf == 0) TheEnd1("colorfunc1 malloc err0\n");
  423.           memset((char *)(cbuf),0x00,(3 * psize) );
  424.  
  425.           if (xa_file_flag == TRUE)
  426.           { ULONG pos;
  427.             data = (UBYTE *)malloc(dlta_hdr->fsize);
  428.             if (data==0) TheEnd1("colorfunc1 malloc err1\n");
  429.             pos = ftell(fin);
  430.             fseek(fin,dlta_hdr->fpos,0); /* save file pos */
  431.             fread(data,dlta_hdr->fsize,1,fin); /* read data*/
  432.             fseek(fin,pos,0); /* restore file pos */
  433.           } else data = dlta_hdr->data;
  434.           dlta_flag = dlta_hdr->delta(cbuf,data,dlta_hdr->fsize,0,
  435.                 0,FALSE,avi_imagex,avi_imagey,8,&xpos,&ypos,&xsize,&ysize,1,0);
  436.           if (xa_file_flag == TRUE) { free(data); data = 0; }
  437.  
  438.     switch(cmap_color_func)
  439.         {
  440.       case 4:
  441.       {
  442.             avi_chdr = CMAP_Create_CHDR_From_True(cbuf,8,8,8,
  443.                               avi_imagex,avi_imagey,avi_cmap,&avi_imagec);
  444.         DEBUG_LEVEL1 fprintf(stderr,"CF4: csize = %ld\n",avi_chdr->csize);
  445.         if (avi_chdr->csize > 128) avi_cmap_flag = 1;
  446.             if (cbuf) free(cbuf); cbuf = 0;
  447.  
  448.       }
  449.       break;
  450.        } /* end switch */
  451.      } /* first time through */
  452.      else  /* else cnt til next time */
  453.      {
  454.        avi_cmap_cnt++;
  455.        if (cmap_sample_cnt && (avi_cmap_cnt >= avi_cmap_frame_num))
  456.                 { avi_cmap_flag = 0; avi_cmap_cnt = 0; }
  457.      }
  458.      } /*color func, true color anim and not TrueDisplay  */
  459.         ACT_Add_CHDR_To_Action(act,avi_chdr);
  460.       } /* not bufferd */
  461.  
  462.       }
  463.       break;
  464.         case RIFF_01wb:
  465.       { ULONG snd_size = ck_size;
  466.         if (ck_size & 0x01) ck_size++;
  467.         if (ck_size == 0) break;
  468.         DEBUG_LEVEL2 
  469.         fprintf(stderr,"01wb audio attemp %lx\n",avi_audio_attempt);
  470. #ifdef POD_AUDIO_BETA
  471.         if (avi_audio_attempt==TRUE)
  472.         { LONG ret;
  473.           UBYTE *snd;
  474.           snd = (UBYTE *)malloc(ck_size);
  475.           if (snd==0) TheEnd1("AVI: snd malloc err");
  476.           ret = fread( snd, ck_size, 1, fin);
  477.           if (ret != 1) fprintf(stderr,"AVI: snd rd err\n");
  478.           else XA_Add_Sound(anim_hdr,snd,avi_audio_type, 0, 
  479.                         avi_audio_freq, snd_size );
  480.         }
  481.         else
  482. #endif
  483.         { /* PODNOTE: SEEK?? */
  484.           for(i=0; i<ck_size; i++) d = getc(fin);
  485.         }
  486.       }
  487.       break;
  488.     case RIFF_00pc:
  489.         { ULONG pc_firstcol,pc_numcols;
  490.           pc_firstcol = getc(fin);
  491.           pc_numcols  = getc(fin);
  492.           d = getc(fin);
  493.           d = getc(fin);
  494.           for(i = 0; i < pc_numcols; i++) 
  495.           {
  496.             avi_cmap[i + pc_firstcol].red   = (getc(fin) & 0xff);
  497.             avi_cmap[i + pc_firstcol].green = (getc(fin) & 0xff);
  498.             avi_cmap[i + pc_firstcol].blue  = (getc(fin) & 0xff);
  499.             d = getc(fin);
  500.           }
  501.           act = ACT_Get_Action(anim_hdr,0);
  502.           AVI_Add_Frame( avi_time ,act);
  503.           avi_chdr = ACT_Get_CMAP(avi_cmap,avi_imagec,0,
  504.                             avi_imagec,0,8,8,8);
  505.           ACT_Add_CHDR_To_Action(act,avi_chdr);
  506.         }
  507.         break;
  508.  
  509.  
  510.  
  511.         case RIFF_idx1:
  512.         case RIFF_vedt:
  513.         case RIFF_strd:
  514.         case RIFF_strl:
  515.         case RIFF_hdrl:
  516.         case RIFF_vids:
  517.         case RIFF_JUNK:
  518.     case RIFF_DISP:
  519.     case RIFF_ISBJ:
  520.     case RIFF_00AM:
  521.                 if (ck_size & 0x01) ck_size++;
  522.                 for(i=0; i<ck_size; i++) d = getc(fin);
  523.                 break;
  524.  
  525.         default:
  526.         if ( !feof(fin) )
  527.         {
  528.             AVI_Print_ID(stderr,ck_id);
  529.                     fprintf(stderr,"  chunk unknown\n");
  530.                     fseek(fin,0,2); /* goto end of file */
  531.         }
  532.  
  533.       } /* end of ck_id switch */
  534.     } /* while not exitflag */
  535.  
  536.   if (avi_pic != 0) { FREE(avi_pic,0xA003); avi_pic=0; }
  537.   fclose(fin);
  538.  
  539.   if (xa_verbose) 
  540.   {
  541.     fprintf(stderr,"AVI %ldx%ldx%ld frames %ld codec ",
  542.             avi_imagex,avi_imagey,avi_imagec,avi_frame_cnt);
  543.     AVI_Print_ID(stderr,avi_compression);
  544.     fprintf(stderr," depth=%ld\n",avi_depth);
  545.   }
  546.   if (avi_frame_cnt == 0)
  547.   { 
  548.     fprintf(stderr,"AVI: No supported video frames exist in this file.\n");
  549.     return(FALSE);
  550.   }
  551.  
  552.   anim_hdr->frame_lst = (XA_FRAME *)
  553.                 malloc( sizeof(XA_FRAME) * (avi_frame_cnt+1));
  554.   if (anim_hdr->frame_lst == NULL) TheEnd1("AVI_Read_File: frame malloc err");
  555.  
  556.   avi_frame_cur = avi_frame_start;
  557.   i = 0;
  558.   while(avi_frame_cur != 0)
  559.   {
  560.     if (i > avi_frame_cnt)
  561.     {
  562.       fprintf(stderr,"AVI_Read_Anim: frame inconsistency %ld %ld\n",
  563.                 i,avi_frame_cnt);
  564.       break;
  565.     }
  566.     anim_hdr->frame_lst[i].time   = avi_frame_cur->time;
  567.     anim_hdr->frame_lst[i].timelo = avi_frame_cur->timelo;
  568.     anim_hdr->frame_lst[i].act = avi_frame_cur->act;
  569.     avi_frame_cur = avi_frame_cur->next;
  570.     i++;
  571.   }
  572.   anim_hdr->imagex = avi_imagex;
  573.   anim_hdr->imagey = avi_imagey;
  574.   anim_hdr->imagec = avi_imagec;
  575.   anim_hdr->imaged = 8; /* nop */
  576.   anim_hdr->frame_lst[i].time = 0;
  577.   anim_hdr->frame_lst[i].timelo = 0;
  578.   anim_hdr->frame_lst[i].act  = 0;
  579.   anim_hdr->loop_frame = 0;
  580.   if (xa_buffer_flag == FALSE) anim_hdr->anim_flags |= ANIM_SNG_BUF;
  581.   if (xa_file_flag == TRUE) anim_hdr->anim_flags |= ANIM_USE_FILE;
  582.   anim_hdr->max_fsize = avi_max_fsize;
  583.   anim_hdr->fname = anim_hdr->name;
  584.   if (i > 0) anim_hdr->last_frame = i - 1;
  585.   else i = 0;
  586.   AVI_Free_Frame_List(avi_frame_start);
  587.   return(TRUE);
  588. } /* end of read file */
  589.  
  590. ULONG RIFF_Read_AVIH(fin,size,avi_hdr)
  591. FILE *fin;
  592. ULONG size;
  593. AVI_HDR *avi_hdr;
  594. {
  595.   if (size != 0x38)
  596.   {
  597.     fprintf(stderr,"avih: size not 56 size=%ld\n",size);
  598.     return(FALSE);
  599.   }
  600.  
  601.   avi_hdr->us_frame     = UTIL_Get_LSB_Long(fin);
  602.   avi_hdr->max_bps      = UTIL_Get_LSB_Long(fin);
  603.   avi_hdr->pad_gran     = UTIL_Get_LSB_Long(fin);
  604.   avi_hdr->flags        = UTIL_Get_LSB_Long(fin);
  605.   avi_hdr->tot_frames   = UTIL_Get_LSB_Long(fin);
  606.   avi_hdr->init_frames  = UTIL_Get_LSB_Long(fin);
  607.   avi_hdr->streams      = UTIL_Get_LSB_Long(fin);
  608.   avi_hdr->sug_bsize    = UTIL_Get_LSB_Long(fin);
  609.   avi_hdr->width        = UTIL_Get_LSB_Long(fin);
  610.   avi_hdr->height       = UTIL_Get_LSB_Long(fin);
  611.   avi_hdr->scale        = UTIL_Get_LSB_Long(fin);
  612.   avi_hdr->rate         = UTIL_Get_LSB_Long(fin);
  613.   avi_hdr->start        = UTIL_Get_LSB_Long(fin);
  614.   avi_hdr->length       = UTIL_Get_LSB_Long(fin);
  615.  
  616.  
  617.   avi_cmap_frame_num = avi_hdr->tot_frames / cmap_sample_cnt;
  618.   if (xa_jiffy_flag) { avi_time = xa_jiffy_flag; avi_timelo = 0; }
  619.   else
  620.   { double ftime = (double)((avi_hdr->us_frame)/1000.0); /* convert to ms */
  621.     avi_time =  (ULONG)(ftime);
  622.     ftime -= (double)(avi_time);
  623.     avi_timelo = (ftime * (double)(1<<24));
  624.   }
  625.   if (avi_hdr->flags & AVIF_MUSTUSEINDEX) avi_use_index_flag = 1;
  626.   else avi_use_index_flag = 0;
  627. #ifdef POD_AUDIO_BETA
  628.   if (xa_verbose)
  629.   {
  630.     fprintf(stderr,"  AVI flags: ");
  631.     if (avi_hdr->flags & AVIF_HASINDEX) fprintf(stderr,"Has_Index ");
  632.     if (avi_hdr->flags & AVIF_MUSTUSEINDEX) fprintf(stderr,"Use_Index ");
  633.     if (avi_hdr->flags & AVIF_ISINTERLEAVED) fprintf(stderr,"Interleaved ");
  634.     if (avi_hdr->flags & AVIF_WASCAPTUREFILE) fprintf(stderr,"Captured ");
  635.     if (avi_hdr->flags & AVIF_COPYRIGHTED) fprintf(stderr,"Copyrighted ");
  636.     fprintf(stderr,"\n");
  637.   }
  638. #endif
  639.   return(TRUE);
  640. }
  641.  
  642. ULONG RIFF_Read_STRH(fin,size,strh_hdr)
  643. FILE *fin;
  644. ULONG size;
  645. AVI_STREAM_HDR *strh_hdr;
  646. {
  647.   ULONG d,tsize;
  648.  
  649.   if (size < 0x24) 
  650.     {fprintf(stderr,"strh: size < 36 size = %ld\n",size); return(FALSE);}
  651.  
  652.   strh_hdr->fcc_type    = UTIL_Get_MSB_Long(fin);
  653.   strh_hdr->fcc_handler = UTIL_Get_MSB_Long(fin);
  654.   strh_hdr->flags       = UTIL_Get_LSB_Long(fin);
  655.   strh_hdr->priority    = UTIL_Get_LSB_Long(fin);
  656.   strh_hdr->init_frames = UTIL_Get_LSB_Long(fin);
  657.   strh_hdr->scale       = UTIL_Get_LSB_Long(fin);
  658.   strh_hdr->rate        = UTIL_Get_LSB_Long(fin);
  659.   strh_hdr->start       = UTIL_Get_LSB_Long(fin);
  660.   strh_hdr->length      = UTIL_Get_LSB_Long(fin);
  661.   strh_hdr->sug_bsize   = UTIL_Get_LSB_Long(fin);
  662.   strh_hdr->quality     = UTIL_Get_LSB_Long(fin);
  663.   strh_hdr->samp_size   = UTIL_Get_LSB_Long(fin);
  664.  
  665.   tsize = 48; if (size & 0x01) size++;
  666.   while(tsize < size) { d = getc(fin); tsize++; }
  667.  
  668. DEBUG_LEVEL2 fprintf(stderr,"AVI TEST handler = %08lx",strh_hdr->fcc_handler);
  669.   return(TRUE);
  670. }
  671.  
  672. ULONG RIFF_Read_VIDS(fin,size,vids_hdr)
  673. FILE *fin;
  674. ULONG size;
  675. VIDS_HDR *vids_hdr;
  676. {
  677.   ULONG d,i,tsize;
  678.  
  679.   vids_hdr->size        = UTIL_Get_LSB_Long(fin);
  680.   vids_hdr->width       = UTIL_Get_LSB_Long(fin);
  681.   vids_hdr->height      = UTIL_Get_LSB_Long(fin);
  682.   vids_hdr->planes      = UTIL_Get_LSB_Short(fin);
  683.   vids_hdr->bit_cnt     = UTIL_Get_LSB_Short(fin);
  684.   vids_hdr->compression = UTIL_Get_MSB_Long(fin);
  685.   vids_hdr->image_size  = UTIL_Get_LSB_Long(fin);
  686.   vids_hdr->xpels_meter = UTIL_Get_LSB_Long(fin);
  687.   vids_hdr->ypels_meter = UTIL_Get_LSB_Long(fin);
  688.   vids_hdr->num_colors  = UTIL_Get_LSB_Long(fin);
  689.   vids_hdr->imp_colors  = UTIL_Get_LSB_Long(fin);
  690.  
  691.  
  692.   avi_compression = vids_hdr->compression;
  693. DEBUG_LEVEL2 fprintf(stderr,"VIDS compression = %08lx\n",avi_compression);
  694.   avi_depth = vids_hdr->bit_cnt;
  695.   avi_imagex = vids_hdr->width;
  696.   avi_imagey = vids_hdr->height;
  697.   avi_imagec = vids_hdr->num_colors;
  698.   if ( (avi_imagec==0) && (avi_depth <= 8) ) avi_imagec = (1 << avi_depth);
  699.   vids_hdr->num_colors = avi_imagec; /* re-update struct */
  700.  
  701.   switch(avi_compression)
  702.   {
  703.     case RIFF_rgb:  avi_compression = RIFF_RGB;  break;
  704.     case RIFF_rle8: avi_compression = RIFF_RLE8; break;
  705.     case RIFF_rle4: avi_compression = RIFF_RLE4; break;
  706.     case RIFF_none: avi_compression = RIFF_NONE; break;
  707.     case RIFF_pack: avi_compression = RIFF_PACK; break;
  708.     case RIFF_tran: avi_compression = RIFF_TRAN; break;
  709.     case RIFF_ccc : avi_compression = RIFF_CCC;  break;
  710.     case RIFF_jpeg: avi_compression = RIFF_JPEG; break;
  711.     case RIFF_rt21: avi_compression = RIFF_RT21;  break;
  712.     case RIFF_CVID:
  713.     QT_Gen_YUV_Tabs(); /* gen YUV tables and fall through */
  714.     case RIFF_MSVC: /* need to be multiple of 4 */
  715.     case RIFF_CRAM: /* need to be multiple of 4 */
  716.     avi_imagex = 4 * ((avi_imagex + 3)/4);
  717.     avi_imagey = 4 * ((avi_imagey + 3)/4);
  718.     break;
  719.     case RIFF_ULTI: /* need to be multiple of 8 */
  720.     avi_imagex = 8 * ((avi_imagex + 7)/8);
  721.     avi_imagey = 8 * ((avi_imagey + 7)/8);
  722.     AVI_ULTI_Gen_YUV();/* generate tables */
  723.     AVI_Ulti_Gen_LTC();
  724.     break;
  725.  
  726.   }
  727.  
  728.   if (avi_depth <= 8)
  729.   {
  730.     for(i=0; i < avi_imagec; i++)
  731.     {
  732.       avi_cmap[i].blue  =  ( getc(fin) ) & 0xff;
  733.       avi_cmap[i].green =  ( getc(fin) ) & 0xff;
  734.       avi_cmap[i].red   =  ( getc(fin) ) & 0xff;
  735.       d = getc(fin); /* pad */
  736.     }
  737.     avi_chdr = ACT_Get_CMAP(avi_cmap,avi_imagec,0,avi_imagec,0,8,8,8);
  738.   }
  739.   else if (   (cmap_true_map_flag == FALSE) /* depth 16 and not true_map */
  740.            || (xa_buffer_flag == FALSE) )
  741.   {
  742.      if (cmap_true_to_332 == TRUE)
  743.              avi_chdr = CMAP_Create_332(avi_cmap,&avi_imagec);
  744.      else    avi_chdr = CMAP_Create_Gray(avi_cmap,&avi_imagec);
  745.   }
  746.   if ( (avi_pic==0) && (xa_buffer_flag == TRUE))
  747.   {
  748.     avi_pic_size = avi_imagex * avi_imagey;
  749.     if ( (cmap_true_map_flag == TRUE) && (avi_depth == 16) )
  750.         avi_pic = (UBYTE *) malloc( 3 * avi_pic_size );
  751.     else avi_pic = (UBYTE *) malloc( XA_PIC_SIZE(avi_pic_size) );
  752.     if (avi_pic == 0) TheEnd1("AVI_Buffer_Action: malloc failed");
  753.   }
  754.  
  755.   /* Read rest of header */
  756.   tsize = vids_hdr->num_colors * 4 + 40; if (size & 0x01) size++;
  757.   while(tsize < size) { d = getc(fin); tsize++; }
  758.   return(TRUE);
  759. }
  760.  
  761. /*
  762.  * Routine to Decode an AVI CRAM chunk
  763.  */
  764.  
  765. #define AVI_CRAM_C1(ip,clr,rdec) { \
  766.  *ip++ = clr; *ip++ = clr; *ip++ = clr; *ip = clr; ip -= rdec; \
  767.  *ip++ = clr; *ip++ = clr; *ip++ = clr; *ip = clr; ip -= rdec; \
  768.  *ip++ = clr; *ip++ = clr; *ip++ = clr; *ip = clr; ip -= rdec; \
  769.  *ip++ = clr; *ip++ = clr; *ip++ = clr; *ip = clr; }
  770.  
  771. #define AVI_CRAM_C2(ip,flag,cA,cB,rdec) { \
  772.   *ip++ =(flag&0x01)?(cB):(cA); *ip++ =(flag&0x02)?(cB):(cA); \
  773.   *ip++ =(flag&0x04)?(cB):(cA); *ip   =(flag&0x08)?(cB):(cA); ip-=rdec; \
  774.   *ip++ =(flag&0x10)?(cB):(cA); *ip++ =(flag&0x20)?(cB):(cA); \
  775.   *ip++ =(flag&0x40)?(cB):(cA); *ip   =(flag&0x80)?(cB):(cA); }
  776.  
  777. #define AVI_CRAM_C4(ip,flag,cA0,cA1,cB0,cB1,rdec) { \
  778.   *ip++ =(flag&0x01)?(cB0):(cA0); *ip++ =(flag&0x02)?(cB0):(cA0); \
  779.   *ip++ =(flag&0x04)?(cB1):(cA1); *ip   =(flag&0x08)?(cB1):(cA1); ip-=rdec; \
  780.   *ip++ =(flag&0x10)?(cB0):(cA0); *ip++ =(flag&0x20)?(cB0):(cA0); \
  781.   *ip++ =(flag&0x40)?(cB1):(cA1); *ip   =(flag&0x80)?(cB1):(cA1); }
  782.  
  783. #define AVI_MIN_MAX_CHECK(x,y,min_x,max_x,min_y,max_y) { \
  784.     if (x < min_x) min_x = x; if (y > max_y) max_y = y; \
  785.     if (x > max_x) max_x = x; if (y < min_y) min_y = y; } 
  786.  
  787. #define AVI_BLOCK_INC(x,y,imagex) { x += 4; if (x>=imagex) { x=0; y -= 4; } }
  788.  
  789. #define AVI_GET_16(data,dptr) { data = *dptr++; data |= (*dptr++) << 8; }
  790.  
  791. #define AVI_CRAM_rgbC1(ip,r,g,b) { \
  792.  *ip++=r; *ip++=g; *ip++=b; *ip++=r; *ip++=g; *ip++=b; \
  793.  *ip++=r; *ip++=g; *ip++=b; *ip++=r; *ip++=g; *ip  =b; }
  794.  
  795. #define AVI_CRAM_rgbC2(ip,flag,rA,gA,bA,rB,gB,bB) { \
  796.   if (flag&0x01) {*ip++=rB; *ip++=gB; *ip++=bB;} \
  797.   else         {*ip++=rA; *ip++=gA; *ip++=bA;} \
  798.   if (flag&0x02) {*ip++=rB; *ip++=gB; *ip++=bB;} \
  799.   else         {*ip++=rA; *ip++=gA; *ip++=bA;} \
  800.   if (flag&0x04) {*ip++=rB; *ip++=gB; *ip++=bB;} \
  801.   else         {*ip++=rA; *ip++=gA; *ip++=bA;} \
  802.   if (flag&0x08) {*ip++=rB; *ip++=gB; *ip  =bB;} \
  803.   else         {*ip++=rA; *ip++=gA; *ip  =bA;}  }
  804.  
  805. #define AVI_CRAM_rgbC4(ip,flag,rA,gA,bA,rB,gB,bB) { \
  806.   if (flag&0x01) {*ip++=rB; *ip++=gB; *ip++=bB;} \
  807.   else         {*ip++=rA; *ip++=gA; *ip++=bA;} \
  808.   if (flag&0x02) {*ip++=rB; *ip++=gB; *ip  =bB;} \
  809.   else         {*ip++=rA; *ip++=gA; *ip  =bA;} }
  810.  
  811. #define AVI_Get_RGBColor(r,g,b,color) \
  812. { register ULONG _r,_g,_b; \
  813.   _r = (color >> 10) & 0x1f; r = (_r << 3) | (_r >> 2); \
  814.   _g = (color >>  5) & 0x1f; g = (_g << 3) | (_g >> 2); \
  815.   _b =  color & 0x1f;        b = (_b << 3) | (_b >> 2); \
  816.   if (xa_gamma_flag==TRUE) { r = xa_gamma_adj[r]>>8;    \
  817.      g = xa_gamma_adj[g]>>8; b = xa_gamma_adj[b]>>8; } }
  818.  
  819.  
  820. ULONG
  821. AVI_Decode_CRAM(image,delta,dsize,chdr,map,map_flag,imagex,imagey,imaged,
  822.                         xs,ys,xe,ye,special,extra)
  823. UBYTE *image;        /* Image Buffer. */
  824. UBYTE *delta;        /* delta data. */
  825. ULONG dsize;        /* delta size */
  826. XA_CHDR *chdr;        /* color map info */
  827. ULONG *map;        /* used if it's going to be remapped. */
  828. ULONG map_flag;        /* whether or not to use remap_map info. */
  829. ULONG imagex,imagey;    /* Size of image buffer. */
  830. ULONG imaged;        /* Depth of Image. (IFF specific) */
  831. ULONG *xs,*ys;        /* pos of changed area. */
  832. ULONG *xe,*ye;        /* size of changed area. */
  833. ULONG special;        /* Special Info. */
  834. ULONG extra;        /* extra info needed to decode delta */
  835. {
  836.   ULONG row_dec,exitflag,changed,block_cnt;
  837.   ULONG code0,code1;
  838.   LONG x,y,min_x,max_x,min_y,max_y;
  839.   UBYTE *dptr;
  840.  
  841.   changed = 0;
  842.   max_x = max_y = 0;    min_x = imagex;    min_y = imagey;
  843.   dptr = delta;
  844.   row_dec = imagex + 3;
  845.   x = 0;
  846.   y = imagey - 1;
  847.   exitflag = 0;
  848.   block_cnt = ((imagex * imagey) >> 4) + 1;
  849.  
  850.   if (map_flag == TRUE)
  851.   {
  852.     if (x11_bytes_pixel == 4)
  853.     {
  854.       while(!exitflag)
  855.       {
  856.     code0 =  *dptr++;    code1 =  *dptr++;    block_cnt--;
  857.     if ( (code1==0) && (code0==0) && !block_cnt ) exitflag = 1;
  858.     else
  859.     {
  860.       if (y < 0) {exitflag = 1; /*fprintf(stderr,"CRAM: ovr err0\n");*/ }
  861.       if ((code1 >= 0x84) && (code1 <= 0x87)) /* skip */
  862.       { ULONG skip = ((code1 - 0x84) << 8) + code0;
  863.         block_cnt -= (skip-1); while(skip--) AVI_BLOCK_INC(x,y,imagex);
  864.       }
  865.       else /* single block encoded */
  866.       {
  867.         if (code1 >= 0x90) /* 8 color quadrant encoding */
  868.         { ULONG cA0,cA1,cB0,cB1;
  869.           ULONG *i_ptr = (ULONG *)(image + ((y * imagex + x) << 2) );
  870.           cB0 = (ULONG)map[*dptr++];  cA0 = (ULONG)map[*dptr++];
  871.           cB1 = (ULONG)map[*dptr++];  cA1 = (ULONG)map[*dptr++];
  872.           AVI_CRAM_C4(i_ptr,code0,cA0,cA1,cB0,cB1,row_dec); i_ptr -=row_dec;
  873.           cB0 = (ULONG)map[*dptr++];  cA0 = (ULONG)map[*dptr++];
  874.           cB1 = (ULONG)map[*dptr++];  cA1 = (ULONG)map[*dptr++];
  875.           AVI_CRAM_C4(i_ptr,code1,cA0,cA1,cB0,cB1,row_dec);
  876.         } else if (code1 < 0x80) /* 2 color encoding */
  877.         { register ULONG clr_A,clr_B;
  878.           ULONG *i_ptr = (ULONG *)(image + ((y * imagex + x) << 2) );
  879.           clr_B = (ULONG)map[*dptr++];   clr_A = (ULONG)map[*dptr++];
  880.           AVI_CRAM_C2(i_ptr,code0,clr_A,clr_B,row_dec); i_ptr -= row_dec;
  881.           AVI_CRAM_C2(i_ptr,code1,clr_A,clr_B,row_dec);
  882.         }
  883.         else /* 1 color encoding */
  884.         { ULONG clr = (ULONG)map[code0]; 
  885.           ULONG *i_ptr = (ULONG *)(image + ((y * imagex + x) << 2) );
  886.           AVI_CRAM_C1(i_ptr,clr,row_dec);
  887.         }
  888.         AVI_MIN_MAX_CHECK(x,y,min_x,max_x,min_y,max_y);
  889.         changed = 1; AVI_BLOCK_INC(x,y,imagex);
  890.       } /* end of single block */
  891.     } /* end of not term code */
  892.       } /* end of not while exit */
  893.     } /* end of 4 bytes pixel */
  894.     else if (x11_bytes_pixel == 2)
  895.     {
  896.       while(!exitflag)
  897.       {
  898.     code0 =  *dptr++;    code1 =  *dptr++;    block_cnt--;
  899.     if ( (code1==0) && (code0==0) && !block_cnt ) exitflag = 1;
  900.     else
  901.     {
  902.       if (y < 0) {exitflag = 1; /*fprintf(stderr,"CRAM: ovr err1\n");*/ }
  903.       if ((code1 >= 0x84) && (code1 <= 0x87)) /* skip */
  904.       { ULONG skip = ((code1 - 0x84) << 8) + code0;
  905.         block_cnt -= (skip-1); while(skip--) AVI_BLOCK_INC(x,y,imagex);
  906.       } else /* single block encoded */
  907.       {
  908.         if (code1 >= 0x90) /* 8 color quadrant encoding */
  909.         {
  910.           USHORT cA0,cA1,cB0,cB1;
  911.           USHORT *i_ptr = (USHORT *)(image + ((y * imagex + x) << 1) );
  912.           cB0 = map[*dptr++];  cA0 = map[*dptr++];
  913.           cB1 = map[*dptr++];  cA1 = map[*dptr++];
  914.           AVI_CRAM_C4(i_ptr,code0,cA0,cA1,cB0,cB1,row_dec); i_ptr -=row_dec;
  915.           cB0 = map[*dptr++];  cA0 = map[*dptr++];
  916.           cB1 = map[*dptr++];  cA1 = map[*dptr++];
  917.           AVI_CRAM_C4(i_ptr,code1,cA0,cA1,cB0,cB1,row_dec);
  918.         } /* end of 8 color quadrant encoding */
  919.         else if (code1 < 0x80) /* 2 color encoding */
  920.         { USHORT clr_A,clr_B;
  921.           USHORT *i_ptr = (USHORT *)(image + ((y * imagex + x) << 1) );
  922.           clr_B = (USHORT)map[*dptr++];   clr_A = (USHORT)map[*dptr++];
  923.           AVI_CRAM_C2(i_ptr,code0,clr_A,clr_B,row_dec); i_ptr -= row_dec;
  924.           AVI_CRAM_C2(i_ptr,code1,clr_A,clr_B,row_dec);
  925.         } /* end of 2 color */
  926.         else /* 1 color encoding */
  927.         { USHORT clr = (USHORT)map[code0];
  928.           USHORT *i_ptr = (USHORT *)(image + ((y * imagex + x) << 1) );
  929.           AVI_CRAM_C1(i_ptr,clr,row_dec);
  930.         }
  931.         AVI_MIN_MAX_CHECK(x,y,min_x,max_x,min_y,max_y);
  932.         changed = 1; AVI_BLOCK_INC(x,y,imagex);
  933.       } /* end of single block */
  934.     } /* end of not term code */
  935.       } /* end of not while exit */
  936.     } /* end of 2 bytes pixel */
  937.     else /* (x11_bytes_pixel == 1) */
  938.     {
  939.       while(!exitflag)
  940.       {
  941.     code0 =  *dptr++;    code1 =  *dptr++;    block_cnt--;
  942.     if ( (code1==0) && (code0==0) && !block_cnt ) exitflag = 1;
  943.     else
  944.     {
  945.       if (y < 0) {exitflag = 1; /*fprintf(stderr,"AVI: ovr err2\n");*/ }
  946.       if ((code1 >= 0x84) && (code1 <= 0x87)) /* skip */
  947.       { ULONG skip = ((code1 - 0x84) << 8) + code0;
  948.         block_cnt -= (skip-1); while(skip--) AVI_BLOCK_INC(x,y,imagex);
  949.       } else /* single block encoded */
  950.       { 
  951.         if (code1 >= 0x90) /* 8 color quadrant encoding */
  952.         { UBYTE cA0,cA1,cB0,cB1;
  953.           UBYTE *i_ptr = (UBYTE *)(image + y * imagex + x);
  954.           cB0 = (UBYTE)map[*dptr++];  cA0 = (UBYTE)map[*dptr++];
  955.           cB1 = (UBYTE)map[*dptr++];  cA1 = (UBYTE)map[*dptr++];
  956.           AVI_CRAM_C4(i_ptr,code0,cA0,cA1,cB0,cB1,row_dec); i_ptr -=row_dec;
  957.           cB0 = (UBYTE)map[*dptr++];  cA0 = (UBYTE)map[*dptr++];
  958.           cB1 = (UBYTE)map[*dptr++];  cA1 = (UBYTE)map[*dptr++];
  959.           AVI_CRAM_C4(i_ptr,code1,cA0,cA1,cB0,cB1,row_dec);
  960.         } 
  961.         else if (code1 < 0x80) /* 2 color encoding */
  962.         { UBYTE clr_A,clr_B;
  963.           UBYTE *i_ptr = (UBYTE *)(image + y * imagex + x);
  964.           clr_B = (UBYTE)map[*dptr++];   clr_A = (UBYTE)map[*dptr++];
  965.           AVI_CRAM_C2(i_ptr,code0,clr_A,clr_B,row_dec); i_ptr -= row_dec;
  966.           AVI_CRAM_C2(i_ptr,code1,clr_A,clr_B,row_dec);
  967.         }
  968.         else /* 1 color encoding */
  969.         { UBYTE clr = (UBYTE)map[code0];
  970.           UBYTE *i_ptr = (UBYTE *)(image + y * imagex + x);
  971.           AVI_CRAM_C1(i_ptr,clr,row_dec);
  972.         }
  973.         AVI_MIN_MAX_CHECK(x,y,min_x,max_x,min_y,max_y);
  974.         changed = 1; AVI_BLOCK_INC(x,y,imagex);
  975.       } /* end of single block */
  976.     } /* end of not term code */
  977.       } /* end of not while exit */
  978.     } /* end of 1 bytes pixel */
  979.   } /* end of map is TRUE */
  980.   else
  981.   {
  982.       while(!exitflag)
  983.       {
  984.     code0 =  *dptr++;    code1 =  *dptr++;    block_cnt--;
  985.     if ( (code1==0) && (code0==0) && !block_cnt ) exitflag = 1;
  986.     else if (y < 0) {exitflag = 1; /*fprintf(stderr,"AVI: ovr err3\n");*/ }
  987.     else
  988.     {
  989.       if ((code1 >= 0x84) && (code1 <= 0x87)) /* skip */
  990.       { ULONG skip = ((code1 - 0x84) << 8) + code0;
  991.         block_cnt -= (skip-1); while(skip--) AVI_BLOCK_INC(x,y,imagex);
  992.       } else /* single block encoded */
  993.       {
  994.         if (code1 >= 0x90) /* 8 color quadrant encoding */
  995.         {
  996.           UBYTE cA0,cA1,cB0,cB1;
  997.           UBYTE *i_ptr = (UBYTE *)(image + y * imagex + x);
  998.           cB0 = (UBYTE)*dptr++;  cA0 = (UBYTE)*dptr++;
  999.           cB1 = (UBYTE)*dptr++;  cA1 = (UBYTE)*dptr++;
  1000.           AVI_CRAM_C4(i_ptr,code0,cA0,cA1,cB0,cB1,row_dec); i_ptr -=row_dec;
  1001.           cB0 = (UBYTE)*dptr++;  cA0 = (UBYTE)*dptr++;
  1002.           cB1 = (UBYTE)*dptr++;  cA1 = (UBYTE)*dptr++;
  1003.           AVI_CRAM_C4(i_ptr,code1,cA0,cA1,cB0,cB1,row_dec);
  1004.         } 
  1005.         else if (code1 < 0x80) /* 2 color encoding */
  1006.         { UBYTE clr_A,clr_B;
  1007.           UBYTE *i_ptr = (UBYTE *)(image + y * imagex + x);
  1008.           clr_B = (UBYTE)*dptr++;   clr_A = (UBYTE)*dptr++;
  1009.           AVI_CRAM_C2(i_ptr,code0,clr_A,clr_B,row_dec); i_ptr -= row_dec;
  1010.           AVI_CRAM_C2(i_ptr,code1,clr_A,clr_B,row_dec);
  1011.         } /* end of 2 color */
  1012.         else /* 1 color encoding */
  1013.         {
  1014.           UBYTE clr = (UBYTE)code0;
  1015.           UBYTE *i_ptr = (UBYTE *)(image + y * imagex + x);
  1016.           AVI_CRAM_C1(i_ptr,clr,row_dec);
  1017.         }
  1018.         AVI_MIN_MAX_CHECK(x,y,min_x,max_x,min_y,max_y);
  1019.         changed = 1; AVI_BLOCK_INC(x,y,imagex);
  1020.       } /* end of single block */
  1021.     } /* end of not term code */
  1022.       } /* end of not while exit */
  1023.   }
  1024.   if (xa_optimize_flag == TRUE)
  1025.   {
  1026.     if (changed) { *xs=min_x; *ys=min_y - 3; *xe=max_x + 4; *ye=max_y + 1; }
  1027.     else  { *xs = *ys = *xe = *ye = 0; return(ACT_DLTA_NOP); }
  1028.   }
  1029.   else { *xs = *ys = 0; *xe = imagex; *ye = imagey; }
  1030.   if (map_flag) return(ACT_DLTA_MAPD);
  1031.   else return(ACT_DLTA_NORM);
  1032. }
  1033.  
  1034.  
  1035. /*
  1036.  * Routine to Decode an AVI RGB chunk
  1037.  * (i.e. just copy it into the image buffer)
  1038.  * courtesy of Julian Bradfield.
  1039.  */
  1040.  
  1041. ULONG
  1042. AVI_Decode_RGB(image,delta,dsize,chdr,map,map_flag,imagex,imagey,imaged,
  1043.                         xs,ys,xe,ye,special,extra)
  1044. UBYTE *image;        /* Image Buffer. */
  1045. UBYTE *delta;        /* delta data. */
  1046. ULONG dsize;        /* delta size */
  1047. XA_CHDR *chdr;        /* color map info */
  1048. ULONG *map;        /* used if it's going to be remapped. */
  1049. ULONG map_flag;        /* whether or not to use remap_map info. */
  1050. ULONG imagex,imagey;    /* Size of image buffer. */
  1051. ULONG imaged;        /* Depth of Image. (IFF specific) */
  1052. ULONG *xs,*ys;        /* pos of changed area. */
  1053. ULONG *xe,*ye;        /* size of changed area. */
  1054. ULONG special;        /* Special Info. */
  1055. ULONG extra;        /* extra info needed to decode delta */
  1056. { ULONG oddflag;
  1057.   UBYTE *dptr = delta;
  1058.   
  1059.   oddflag = imagex & 0x01;
  1060.   if (map_flag == TRUE)
  1061.   {
  1062.     if (x11_bytes_pixel == 4)
  1063.     { LONG x,y = imagey - 1;
  1064.       while ( y >= 0 )
  1065.       { ULONG *i_ptr = (ULONG *)(image + ((y * imagex)<<2) ); y--; 
  1066.         x = imagex; while(x--) *i_ptr++ = (ULONG)map[*dptr++];
  1067.     if (oddflag) dptr++;
  1068.       }
  1069.     }
  1070.     else if (x11_bytes_pixel == 2)
  1071.     { LONG x,y = imagey - 1;
  1072.       while ( y >= 0 )
  1073.       { USHORT *i_ptr = (USHORT *)(image + ((y * imagex)<<1) ); y--; 
  1074.         x = imagex; while(x--) *i_ptr++ = (USHORT)map[*dptr++];
  1075.     if (oddflag) dptr++;
  1076.       }
  1077.     }
  1078.     else /* (x11_bytes_pixel == 1) */
  1079.     { LONG x,y = imagey - 1;
  1080.       while ( y >= 0 )
  1081.       { UBYTE *i_ptr = (UBYTE *)(image + y * imagex); y--; 
  1082.         x = imagex; while(x--) *i_ptr++ = (UBYTE)map[*dptr++];
  1083.     if (oddflag) dptr++;
  1084.       }
  1085.     }
  1086.   } /* end of map is TRUE */
  1087.   else
  1088.   { LONG x,y = imagey - 1;
  1089.     while ( y >= 0 )
  1090.     { UBYTE *i_ptr = (UBYTE *)(image + y * imagex); y--; 
  1091.       x = imagex; while(x--) *i_ptr++ = (UBYTE)*dptr++;
  1092.     if (oddflag) dptr++;
  1093.     }
  1094.   }
  1095.  *xs = *ys = 0; *xe = imagex; *ye = imagey;
  1096.   if (map_flag) return(ACT_DLTA_MAPD);
  1097.   else return(ACT_DLTA_NORM);
  1098. }
  1099.  
  1100. void AVI_Print_ID(fout,id)
  1101. FILE *fout;
  1102. LONG id;
  1103. {
  1104.  fprintf(fout,"%c",     ((id >> 24) & 0xff)   );
  1105.  fprintf(fout,"%c",     ((id >> 16) & 0xff)   );
  1106.  fprintf(fout,"%c",     ((id >>  8) & 0xff)   );
  1107.  fprintf(fout,"%c(%lx)", (id        & 0xff),id);
  1108. }
  1109.  
  1110.  
  1111. ULONG AVI_Get_Color(color,map_flag,map,chdr)
  1112. ULONG color,map_flag,*map;
  1113. XA_CHDR *chdr;
  1114. {
  1115.   register ULONG clr,ra,ga,ba,tr,tg,tb;
  1116.  
  1117.   ra = (color >> 10) & 0x1f;
  1118.   ga = (color >>  5) & 0x1f;
  1119.   ba =  color & 0x1f;
  1120.   tr = (ra << 3) | (ra >> 2);
  1121.   tg = (ga << 3) | (ga >> 2);
  1122.   tb = (ba << 3) | (ba >> 2);
  1123.   if (xa_gamma_flag==TRUE) { tr = xa_gamma_adj[tr]>>8;  
  1124.      tg = xa_gamma_adj[tg]>>8; tb = xa_gamma_adj[tb]>>8; }
  1125.  
  1126.  
  1127.   if (x11_display_type & XA_X11_TRUE) clr = X11_Get_True_Color(ra,ga,ba,5);
  1128.   else
  1129.   { 
  1130.     if ((cmap_color_func == 4) && (chdr))
  1131.     { register ULONG cache_i = color & 0x7fff;
  1132.       if (cmap_cache == 0) CMAP_Cache_Init();
  1133.       if (chdr != cmap_cache_chdr)
  1134.       {
  1135.     CMAP_Cache_Clear();
  1136.     cmap_cache_chdr = chdr;
  1137.       }
  1138.       if (cmap_cache[cache_i] == 0xffff)
  1139.       {
  1140.         clr = chdr->coff + 
  1141.        CMAP_Find_Closest(chdr->cmap,chdr->csize,ra,ga,ba,5,5,5,TRUE);
  1142.         cmap_cache[cache_i] = (USHORT)clr;
  1143.       }
  1144.       else clr = (ULONG)cmap_cache[cache_i];
  1145.     }
  1146.     else
  1147.     {
  1148.       if (cmap_true_to_332 == TRUE) 
  1149.       clr=CMAP_GET_332(ra,ga,ba,CMAP_SCALE5);
  1150.       else   clr = CMAP_GET_GRAY(ra,ga,ba,CMAP_SCALE10);
  1151.       if (map_flag) clr = map[clr];
  1152.     }
  1153.   }
  1154.   return(clr);
  1155. }
  1156.  
  1157.  
  1158. ULONG
  1159. AVI_Decode_RLE8(image,delta,dsize,chdr,map,map_flag,imagex,imagey,imaged,
  1160.                                                 xs,ys,xe,ye,special,extra)
  1161. UBYTE *image;           /* Image Buffer. */
  1162. UBYTE *delta;           /* delta data. */
  1163. LONG dsize;             /* delta size */
  1164. XA_CHDR *chdr;          /* color map info */
  1165. ULONG *map;             /* used if it's going to be remapped. */
  1166. ULONG map_flag;         /* whether or not to use remap_map info. */
  1167. ULONG imagex,imagey;    /* Size of image buffer. */
  1168. ULONG imaged;           /* Depth of Image. (IFF specific) */
  1169. ULONG *xs,*ys;          /* pos of changed area. */
  1170. ULONG *xe,*ye;          /* size of changed area. */
  1171. ULONG special;          /* Special Info. */
  1172. ULONG extra;            /* extra info needed to decode delta */
  1173. {
  1174.   ULONG opcode,mod;
  1175.   LONG x,y,min_x,max_x,min_y,max_y;
  1176.   UBYTE *dptr;
  1177.  
  1178.   max_x = max_y = 0; min_x = imagex; min_y = imagey;
  1179.   x = 0;  y = imagey - 1;
  1180.   dptr = delta;
  1181.  
  1182.   while( (y >= 0) && (dsize > 0) )
  1183.   {
  1184.     mod = *dptr++;
  1185.     opcode = *dptr++;  dsize-=2;
  1186.  
  1187.     if (mod == 0x00)                /* END-OF-LINE */
  1188.     {
  1189.       if (opcode==0x00)
  1190.       {
  1191.         while(x > imagex) { x -=imagex; y--; }
  1192.         x = 0; y--;
  1193.       }
  1194.       else if (opcode==0x01)            /* END Of Image */
  1195.       {
  1196.         y = -1;
  1197.       }
  1198.       else if (opcode==0x02)            /* SKIP */
  1199.       {
  1200.         ULONG yskip,xskip;
  1201.         xskip = *dptr++; 
  1202.         yskip = *dptr++;  dsize-=2;
  1203.         x += xskip;
  1204.         y -= yskip;
  1205.       }
  1206.       else                    /* ABSOLUTE MODE */
  1207.       {
  1208.         int cnt = opcode;
  1209.         
  1210.     dsize-=cnt;
  1211.         while(x >= imagex) { x -= imagex; y--; }
  1212.     if (y > max_y) max_y = y; if (x < min_x) x = min_x;
  1213.         if (map_flag==TRUE)
  1214.     {
  1215.       if (x11_bytes_pixel==1)
  1216.           { UBYTE *iptr = (UBYTE *)(image + (y * imagex + x) );
  1217.             while(cnt--) 
  1218.         { if (x >= imagex) { max_x = imagex; min_x = 0;
  1219.          x -= imagex; y--; iptr = (UBYTE *)(image+y*imagex+x); }
  1220.               *iptr++ = (UBYTE)map[*dptr++];  x++;
  1221.         }
  1222.       }
  1223.       else if (x11_bytes_pixel==2)
  1224.           { USHORT *iptr = (USHORT *)(image + ((y * imagex + x)<<1) );
  1225.             while(cnt--) 
  1226.         { if (x >= imagex)  { max_x = imagex; min_x = 0;
  1227.         x -= imagex; y--; iptr = (USHORT *)(image+y*imagex+x); }
  1228.               *iptr++ = (USHORT)map[*dptr++];  x++;
  1229.         }
  1230.       }
  1231.       else /* if (x11_bytes_pixel==4) */
  1232.           { ULONG *iptr = (ULONG *)(image + ((y * imagex + x)<<2) );
  1233.             while(cnt--) 
  1234.         { if (x >= imagex)  { max_x = imagex; min_x = 0;
  1235.         x -= imagex; y--; iptr = (ULONG *)(image+y*imagex+x); }
  1236.               *iptr++ = (ULONG)map[*dptr++];  x++;
  1237.         }
  1238.       }
  1239.         }
  1240.         else
  1241.         { UBYTE *iptr = (UBYTE *)(image + (y * imagex + x) );
  1242.           while(cnt--) 
  1243.       { if (x >= imagex)  { max_x = imagex; min_x = 0;
  1244.         x -=imagex; y--; iptr = (UBYTE *)(image+y*imagex+x); }
  1245.         *iptr++ = (UBYTE)(*dptr++); x++;
  1246.       }
  1247.         }
  1248.         if (opcode & 0x01) { dptr++; dsize--; }
  1249.         if (y < min_y) min_y = y; if (x > max_x) x = max_x;
  1250.       }
  1251.     }
  1252.     else                    /* ENCODED MODE */
  1253.     {
  1254.       int color,cnt;
  1255.       while(x >= imagex) { x -=imagex; y--; }
  1256.       if (y > max_y) max_y = y; if (x < min_x) x = min_x;
  1257.       cnt = mod;
  1258.       color = (map_flag==TRUE)?(map[opcode]):(opcode);
  1259.       if ( (map_flag==FALSE) || (x11_bytes_pixel==1) )
  1260.       { UBYTE *iptr = (UBYTE *)(image + (y * imagex + x) );
  1261.     UBYTE clr = (UBYTE)color;
  1262.     while(cnt--) 
  1263.     { if (x >= imagex) { max_x = imagex; min_x = 0;
  1264.         x -=imagex; y--; iptr = (UBYTE *)(image+y*imagex+x); }
  1265.       *iptr++ = clr; x++;
  1266.     }
  1267.       }
  1268.       else if (x11_bytes_pixel==2)
  1269.       { USHORT *iptr = (USHORT *)(image + ((y * imagex + x)<<1) );
  1270.     USHORT clr = (USHORT)color;
  1271.     while(cnt--) 
  1272.     { if (x >= imagex)  { max_x = imagex; min_x = 0;
  1273.         x -=imagex; y--; iptr = (USHORT *)(image+y*imagex+x); }
  1274.       *iptr++ = clr; x++;
  1275.     }
  1276.       }
  1277.       else /* if (x11_bytes_pixel==4) */
  1278.       { ULONG *iptr = (ULONG *)(image + ((y * imagex + x)<<2) );
  1279.     ULONG clr = (ULONG)color;
  1280.     while(cnt--) 
  1281.     { if (x >= imagex)  { max_x = imagex; min_x = 0;
  1282.         x -=imagex; y--; iptr = (ULONG *)(image+y*imagex+x); }
  1283.       *iptr++ = clr; x++;
  1284.     }
  1285.       }
  1286.       if (y < min_y) min_y = y; if (x > max_x) x = max_x;
  1287.     }
  1288.   } /* end of while */
  1289.  
  1290.   if (xa_optimize_flag == TRUE)
  1291.   {
  1292.     max_x++; if (max_x>imagex) max_x=imagex;
  1293.     max_y++; if (max_y>imagey) max_y=imagey;
  1294.     if ((min_x >= max_x) || (min_y >= max_y)) /* no change */
  1295.         { *xs = *ys = *xe = *ye = 0; return(ACT_DLTA_NOP); }
  1296.     else    { *xs=min_x; *ys=min_y; *xe=max_x; *ye=max_y; }
  1297.   }
  1298.   else { *xs = *ys = 0; *xe = imagex; *ye = imagey; }
  1299.   if (map_flag) return(ACT_DLTA_MAPD);
  1300.   else return(ACT_DLTA_NORM);
  1301. }
  1302.  
  1303. ULONG
  1304. AVI_Decode_CRAM16(image,delta,dsize,tchdr,map,map_flag,imagex,imagey,imaged,
  1305.                         xs,ys,xe,ye,special,extra)
  1306. UBYTE *image;        /* Image Buffer. */
  1307. UBYTE *delta;        /* delta data. */
  1308. ULONG dsize;        /* delta size */
  1309. XA_CHDR *tchdr;        /* color map info */
  1310. ULONG *map;        /* used if it's going to be remapped. */
  1311. ULONG map_flag;        /* whether or not to use remap_map info. */
  1312. ULONG imagex,imagey;    /* Size of image buffer. */
  1313. ULONG imaged;        /* Depth of Image. (IFF specific) */
  1314. ULONG *xs,*ys;        /* pos of changed area. */
  1315. ULONG *xe,*ye;        /* size of changed area. */
  1316. ULONG special;        /* Special Info. */
  1317. ULONG extra;        /* extra info needed to decode delta */
  1318. {
  1319.   ULONG row_dec,exitflag,changed,block_cnt;
  1320.   ULONG code0,code1;
  1321.   LONG x,y,min_x,max_x,min_y,max_y;
  1322.   UBYTE *dptr;
  1323.   XA_CHDR *chdr;
  1324.  
  1325.   if (tchdr) {chdr=(tchdr->new_chdr)?(tchdr->new_chdr):(tchdr);} else chdr=0;
  1326.   changed = 0;
  1327.   max_x = max_y = 0;    min_x = imagex;    min_y = imagey;
  1328.   dptr = delta;
  1329.   if (special) row_dec = (3*(imagex+4))-1; else row_dec = imagex + 3; 
  1330.   x = 0;
  1331.   y = imagey - 1;
  1332.   exitflag = 0;
  1333.   block_cnt = ((imagex * imagey) >> 4) + 1;
  1334.  
  1335.   if (special == 1)
  1336.   {
  1337.     while(!exitflag)
  1338.     {
  1339.       code0 =  *dptr++;    code1 =  *dptr++;    block_cnt--;
  1340.       if ( (code1==0) && (code0==0) && !block_cnt) { exitflag = 1; continue; }
  1341.       if (y < 0) {exitflag = 1; /* fprintf(stderr,"AVI: CRAM16 ovr err0\n");*/ }
  1342.       if ((code1 >= 0x84) && (code1 <= 0x87)) /* skip */
  1343.       { ULONG skip = ((code1 - 0x84) << 8) + code0;
  1344.     block_cnt -= (skip-1); while(skip--) AVI_BLOCK_INC(x,y,imagex);
  1345.       }
  1346.       else /* not skip */
  1347.       { UBYTE *i_ptr = (UBYTE *)(image + 3 * (y * imagex + x) );
  1348.     if (code1 < 0x80) /* 2 or 8 color encoding */
  1349.     { ULONG cA,cB; UBYTE rA0,gA0,bA0,rB0,gB0,bB0;
  1350.       AVI_GET_16(cB,dptr); AVI_Get_RGBColor(rB0,gB0,bB0,cB);
  1351.       AVI_GET_16(cA,dptr); AVI_Get_RGBColor(rA0,gA0,bA0,cA); 
  1352.       if (cB & 0x8000)   /* Eight Color Encoding */
  1353.       { UBYTE rA1,gA1,bA1,rB1,gB1,bB1;
  1354.         register flag = code0;
  1355.         AVI_GET_16(cB,dptr); AVI_Get_RGBColor(rB1,gB1,bB1,cB);
  1356.         AVI_GET_16(cA,dptr); AVI_Get_RGBColor(rA1,gA1,bA1,cA); 
  1357.         AVI_CRAM_rgbC4(i_ptr,flag,rA0,gA0,bA0,rB0,gB0,bB0); 
  1358.         i_ptr++; flag >>= 2;
  1359.         AVI_CRAM_rgbC4(i_ptr,flag,rA1,gA1,bA1,rB1,gB1,bB1); 
  1360.         i_ptr -= row_dec; flag >>= 2;
  1361.         AVI_CRAM_rgbC4(i_ptr,flag,rA0,gA0,bA0,rB0,gB0,bB0); 
  1362.         i_ptr++; flag >>= 2;
  1363.         AVI_CRAM_rgbC4(i_ptr,flag,rA1,gA1,bA1,rB1,gB1,bB1); 
  1364.         i_ptr -= row_dec; flag = code1;
  1365.         AVI_GET_16(cB,dptr); AVI_Get_RGBColor(rB0,gB0,bB0,cB);
  1366.         AVI_GET_16(cA,dptr); AVI_Get_RGBColor(rA0,gA0,bA0,cA); 
  1367.         AVI_GET_16(cB,dptr); AVI_Get_RGBColor(rB1,gB1,bB1,cB);
  1368.         AVI_GET_16(cA,dptr); AVI_Get_RGBColor(rA1,gA1,bA1,cA); 
  1369.         AVI_CRAM_rgbC4(i_ptr,flag,rA0,gA0,bA0,rB0,gB0,bB0); 
  1370.         i_ptr++; flag >>= 2;
  1371.         AVI_CRAM_rgbC4(i_ptr,flag,rA1,gA1,bA1,rB1,gB1,bB1); 
  1372.         i_ptr -= row_dec; flag >>= 2;
  1373.         AVI_CRAM_rgbC4(i_ptr,flag,rA0,gA0,bA0,rB0,gB0,bB0); 
  1374.         i_ptr++; flag >>= 2;
  1375.         AVI_CRAM_rgbC4(i_ptr,flag,rA1,gA1,bA1,rB1,gB1,bB1); 
  1376.       } else /* Two Color Encoding */
  1377.       { register ULONG flag = code0;
  1378.         AVI_CRAM_rgbC2(i_ptr,flag,rA0,gA0,bA0,rB0,gB0,bB0); 
  1379.         i_ptr -= row_dec; flag >>= 4;
  1380.         AVI_CRAM_rgbC2(i_ptr,flag,rA0,gA0,bA0,rB0,gB0,bB0); 
  1381.         i_ptr -= row_dec; flag = code1;
  1382.         AVI_CRAM_rgbC2(i_ptr,flag,rA0,gA0,bA0,rB0,gB0,bB0); 
  1383.         i_ptr -= row_dec; flag >>= 4;
  1384.         AVI_CRAM_rgbC2(i_ptr,flag,rA0,gA0,bA0,rB0,gB0,bB0); 
  1385.       }
  1386.     } /* end of 2 or 8 */
  1387.     else /* 1 color encoding (80-83) && (>=88)*/
  1388.     { ULONG cA = (code1<<8) | code0;
  1389.       UBYTE r,g,b;
  1390.       AVI_Get_RGBColor(r,g,b,cA);
  1391.       AVI_CRAM_rgbC1(i_ptr,r,g,b);  i_ptr -= row_dec;
  1392.       AVI_CRAM_rgbC1(i_ptr,r,g,b);  i_ptr -= row_dec;
  1393.       AVI_CRAM_rgbC1(i_ptr,r,g,b);  i_ptr -= row_dec;
  1394.       AVI_CRAM_rgbC1(i_ptr,r,g,b);
  1395.     }
  1396.     changed = 1; AVI_MIN_MAX_CHECK(x,y,min_x,max_x,min_y,max_y);
  1397.     AVI_BLOCK_INC(x,y,imagex);
  1398.       } /* end of not skip */
  1399.     } /* end of not while exit */
  1400.   } /* end of special */
  1401.   else
  1402.   {
  1403.     if ( (x11_bytes_pixel == 1) || (map_flag == FALSE) )
  1404.     {
  1405.       while(!exitflag)
  1406.       {
  1407.     code0 =  *dptr++;    code1 =  *dptr++;    block_cnt--;
  1408.     if ( (code1==0) && (code0==0) && !block_cnt) { exitflag = 1; continue; }
  1409.     if (y < 0) {exitflag = 1; continue; }
  1410.     if ((code1 >= 0x84) && (code1 <= 0x87)) /* skip */
  1411.     { ULONG skip = ((code1 - 0x84) << 8) + code0;
  1412.       block_cnt -= (skip-1); while(skip--) AVI_BLOCK_INC(x,y,imagex);
  1413.     }
  1414.     else /* not skip */
  1415.     { UBYTE *i_ptr = (UBYTE *)(image + (y * imagex + x) );
  1416.       if (code1 < 0x80) /* 2 or 8 color encoding */
  1417.       { ULONG cA,cB; UBYTE cA0,cB0;
  1418.         AVI_GET_16(cB,dptr); AVI_GET_16(cA,dptr);
  1419.         cB0 = (UBYTE)AVI_Get_Color(cB,map_flag,map,chdr);
  1420.         cA0 = (UBYTE)AVI_Get_Color(cA,map_flag,map,chdr);
  1421.         if (cB & 0x8000)   /* Eight Color Encoding */
  1422.         { UBYTE cA1,cB1;
  1423.           AVI_GET_16(cB,dptr); AVI_GET_16(cA,dptr);
  1424.           cB1 = (UBYTE)AVI_Get_Color(cB,map_flag,map,chdr);
  1425.           cA1 = (UBYTE)AVI_Get_Color(cA,map_flag,map,chdr);
  1426.           AVI_CRAM_C4(i_ptr,code0,cA0,cA1,cB0,cB1,row_dec); i_ptr -=row_dec;
  1427.           AVI_GET_16(cB,dptr); AVI_GET_16(cA,dptr);
  1428.           cB0 = (UBYTE)AVI_Get_Color(cB,map_flag,map,chdr);
  1429.           cA0 = (UBYTE)AVI_Get_Color(cA,map_flag,map,chdr);
  1430.           AVI_GET_16(cB,dptr); AVI_GET_16(cA,dptr);
  1431.           cB1 = (UBYTE)AVI_Get_Color(cB,map_flag,map,chdr);
  1432.           cA1 = (UBYTE)AVI_Get_Color(cA,map_flag,map,chdr);
  1433.           AVI_CRAM_C4(i_ptr,code1,cA0,cA1,cB0,cB1,row_dec);
  1434.         } else /* Two Color Encoding */
  1435.         { 
  1436.           AVI_CRAM_C2(i_ptr,code0,cA0,cB0,row_dec); i_ptr -= row_dec;
  1437.           AVI_CRAM_C2(i_ptr,code1,cA0,cB0,row_dec);
  1438.         }
  1439.       } /* end of 2 or 8 */
  1440.       else /* 1 color encoding (80-83) && (>=88)*/
  1441.       { ULONG cA = (code1<<8) | code0;
  1442.         UBYTE clr = (UBYTE)AVI_Get_Color(cA,map_flag,map,chdr);
  1443.         AVI_CRAM_C1(i_ptr,clr,row_dec);
  1444.       }
  1445.       changed = 1; AVI_MIN_MAX_CHECK(x,y,min_x,max_x,min_y,max_y);
  1446.       AVI_BLOCK_INC(x,y,imagex);
  1447.     } /* end of not skip */
  1448.       } /* end of not while exit */
  1449.     } /* end of 1 bytes pixel */
  1450.     else if (x11_bytes_pixel == 2)
  1451.     {
  1452.       while(!exitflag)
  1453.       {
  1454.     code0 =  *dptr++;    code1 =  *dptr++;    block_cnt--;
  1455.     if ( (code1==0) && (code0==0) && !block_cnt) { exitflag = 1; continue; }
  1456.     if (y < 0) {exitflag = 1; /*fprintf(stderr,"AVI: CRAM16 ovr err2\n");*/}
  1457.     if ((code1 >= 0x84) && (code1 <= 0x87)) /* skip */
  1458.     { ULONG skip = ((code1 - 0x84) << 8) + code0;
  1459.       block_cnt -= (skip-1); while(skip--) AVI_BLOCK_INC(x,y,imagex);
  1460.     }
  1461.     else /* not skip */
  1462.     { USHORT *i_ptr = (USHORT *)(image + ((y * imagex + x) << 1) );
  1463.       if (code1 < 0x80) /* 2 or 8 color encoding */
  1464.       { ULONG cA,cB; USHORT cA0,cB0;
  1465.         AVI_GET_16(cB,dptr); AVI_GET_16(cA,dptr);
  1466.         cB0 = (USHORT)AVI_Get_Color(cB,map_flag,map,chdr);
  1467.         cA0 = (USHORT)AVI_Get_Color(cA,map_flag,map,chdr);
  1468.         if (cB & 0x8000)   /* Eight Color Encoding */
  1469.         { USHORT cA1,cB1;
  1470.           AVI_GET_16(cB,dptr); AVI_GET_16(cA,dptr);
  1471.           cB1 = (USHORT)AVI_Get_Color(cB,map_flag,map,chdr);
  1472.           cA1 = (USHORT)AVI_Get_Color(cA,map_flag,map,chdr);
  1473.           AVI_CRAM_C4(i_ptr,code0,cA0,cA1,cB0,cB1,row_dec); i_ptr -=row_dec;
  1474.           AVI_GET_16(cB,dptr); AVI_GET_16(cA,dptr);
  1475.           cB0 = (USHORT)AVI_Get_Color(cB,map_flag,map,chdr);
  1476.           cA0 = (USHORT)AVI_Get_Color(cA,map_flag,map,chdr);
  1477.           AVI_GET_16(cB,dptr); AVI_GET_16(cA,dptr);
  1478.           cB1 = (USHORT)AVI_Get_Color(cB,map_flag,map,chdr);
  1479.           cA1 = (USHORT)AVI_Get_Color(cA,map_flag,map,chdr);
  1480.           AVI_CRAM_C4(i_ptr,code1,cA0,cA1,cB0,cB1,row_dec);
  1481.         } else /* Two Color Encoding */
  1482.         { 
  1483.           AVI_CRAM_C2(i_ptr,code0,cA0,cB0,row_dec); i_ptr -= row_dec;
  1484.           AVI_CRAM_C2(i_ptr,code1,cA0,cB0,row_dec);
  1485.         }
  1486.       } /* end of 2 or 8 */
  1487.       else /* 1 color encoding (80-83) && (>=88)*/
  1488.       { ULONG cA = (code1<<8) | code0;
  1489.         USHORT clr = (USHORT)AVI_Get_Color(cA,map_flag,map,chdr);
  1490.         AVI_CRAM_C1(i_ptr,clr,row_dec);
  1491.       }
  1492.       changed = 1; AVI_MIN_MAX_CHECK(x,y,min_x,max_x,min_y,max_y);
  1493.       AVI_BLOCK_INC(x,y,imagex);
  1494.     } /* end of not skip */
  1495.       } /* end of not while exit */
  1496.     } /* end of 2 bytes pixel */
  1497.     else if (x11_bytes_pixel == 4)
  1498.     {
  1499.       while(!exitflag)
  1500.       {
  1501.     code0 =  *dptr++;    code1 =  *dptr++;    block_cnt--;
  1502.     if ( (code1==0) && (code0==0) && !block_cnt) { exitflag = 1; continue; }
  1503.     if (y < 0) {exitflag = 1; /*fprintf(stderr,"AVI: CRAM16 ovr err4\n");*/ }
  1504.     if ((code1 >= 0x84) && (code1 <= 0x87)) /* skip */
  1505.     { ULONG skip = ((code1 - 0x84) << 8) + code0;
  1506.       block_cnt -= (skip-1); while(skip--) AVI_BLOCK_INC(x,y,imagex);
  1507.     }
  1508.     else /* not skip */
  1509.     { ULONG *i_ptr = (ULONG *)(image + ((y * imagex + x) << 2) );
  1510.       if (code1 < 0x80) /* 2 or 8 color encoding */
  1511.       { ULONG cA,cB,cA0,cB0;
  1512.         AVI_GET_16(cB,dptr); AVI_GET_16(cA,dptr);
  1513.         cB0 = AVI_Get_Color(cB,map_flag,map,chdr);
  1514.         cA0 = AVI_Get_Color(cA,map_flag,map,chdr);
  1515.         if (cB & 0x8000)   /* Eight Color Encoding */
  1516.         { ULONG cA1,cB1;
  1517.           AVI_GET_16(cB,dptr); AVI_GET_16(cA,dptr);
  1518.           cB1 = AVI_Get_Color(cB,map_flag,map,chdr);
  1519.           cA1 = AVI_Get_Color(cA,map_flag,map,chdr);
  1520.           AVI_CRAM_C4(i_ptr,code0,cA0,cA1,cB0,cB1,row_dec); i_ptr -=row_dec;
  1521.           AVI_GET_16(cB,dptr); AVI_GET_16(cA,dptr);
  1522.           cB0 = AVI_Get_Color(cB,map_flag,map,chdr);
  1523.           cA0 = AVI_Get_Color(cA,map_flag,map,chdr);
  1524.           AVI_GET_16(cB,dptr); AVI_GET_16(cA,dptr);
  1525.           cB1 = AVI_Get_Color(cB,map_flag,map,chdr);
  1526.           cA1 = AVI_Get_Color(cA,map_flag,map,chdr);
  1527.           AVI_CRAM_C4(i_ptr,code1,cA0,cA1,cB0,cB1,row_dec);
  1528.         } else /* Two Color Encoding */
  1529.         {
  1530.           AVI_CRAM_C2(i_ptr,code0,cA0,cB0,row_dec); i_ptr -= row_dec;
  1531.           AVI_CRAM_C2(i_ptr,code1,cA0,cB0,row_dec);
  1532.         }
  1533.       } /* end of 2 or 8 */
  1534.       else /* 1 color encoding (80-83) && (>=88)*/
  1535.       { ULONG cA = (code1<<8) | code0;
  1536.         ULONG clr = AVI_Get_Color(cA,map_flag,map,chdr);
  1537.         AVI_CRAM_C1(i_ptr,clr,row_dec);
  1538.       }
  1539.       changed = 1; AVI_MIN_MAX_CHECK(x,y,min_x,max_x,min_y,max_y);
  1540.       AVI_BLOCK_INC(x,y,imagex);
  1541.     } /* end of not skip */
  1542.       } /* end of not while exit */
  1543.     } /* end of 4 bytes pixel */
  1544.   } /* end of not special */
  1545.   if (xa_optimize_flag == TRUE)
  1546.   {
  1547.     if (changed) { *xs=min_x; *ys=min_y - 3; *xe=max_x + 4; *ye=max_y + 1; }
  1548.     else  { *xs = *ys = *xe = *ye = 0; return(ACT_DLTA_NOP); }
  1549.   }
  1550.   else { *xs = *ys = 0; *xe = imagex; *ye = imagey; }
  1551.   if (map_flag) return(ACT_DLTA_MAPD);
  1552.   else return(ACT_DLTA_NORM);
  1553. }
  1554.  
  1555. #define ULTI_CHROM_NORM 0
  1556. #define ULTI_CHROM_UNIQ 1
  1557. #define ULTI_STREAM0 0x0
  1558. #define ULTI_STREAM1 0x4
  1559.  
  1560. #define AVI_ULTI_C2(ip,flag,CST,c0,c1,rinc) { \
  1561.   *ip++ =(CST)((flag&0x80)?(c1):(c0)); *ip++ =(CST)(flag&0x40)?(c1):(c0); \
  1562.   *ip++ =(CST)((flag&0x20)?(c1):(c0)); *ip++ =(CST)(flag&0x10)?(c1):(c0);  \
  1563.   ip += rinc; \
  1564.   *ip++ =(CST)((flag&0x08)?(c1):(c0)); *ip++ =(CST)(flag&0x04)?(c1):(c0); \
  1565.   *ip++ =(CST)((flag&0x02)?(c1):(c0)); *ip++ =(CST)(flag&0x01)?(c1):(c0); }
  1566.  
  1567. #define AVI_ULTI_rgbC2(p,msk,r0,r1,g0,g1,b0,b1,rinc) { \
  1568.  if (msk&0x80) {*p++=r0; *p++=g0; *p++=b0;} else {*p++=r1; *p++=g1; *p++=b1;} \
  1569.  if (msk&0x40) {*p++=r0; *p++=g0; *p++=b0;} else {*p++=r1; *p++=g1; *p++=b1;} \
  1570.  if (msk&0x20) {*p++=r0; *p++=g0; *p++=b0;} else {*p++=r1; *p++=g1; *p++=b1;} \
  1571.  if (msk&0x10) {*p++=r0; *p++=g0; *p++=b0;} else {*p++=r1; *p++=g1; *p++=b1;} \
  1572.  p += rinc; \
  1573.  if (msk&0x08) {*p++=r0; *p++=g0; *p++=b0;} else {*p++=r1; *p++=g1; *p++=b1;} \
  1574.  if (msk&0x04) {*p++=r0; *p++=g0; *p++=b0;} else {*p++=r1; *p++=g1; *p++=b1;} \
  1575.  if (msk&0x02) {*p++=r0; *p++=g0; *p++=b0;} else {*p++=r1; *p++=g1; *p++=b1;} \
  1576.  if (msk&0x01) {*p++=r0; *p++=g0; *p++=b0;} else {*p++=r1; *p++=g1; *p++=b1;} }
  1577.  
  1578. ULONG
  1579. AVI_Decode_ULTI(image,delta,dsize,tchdr,map,map_flag,imagex,imagey,imaged,
  1580.                         xs,ys,xe,ye,special,extra)
  1581. UBYTE *image;        /* Image Buffer. */
  1582. UBYTE *delta;        /* delta data. */
  1583. ULONG dsize;        /* delta size */
  1584. XA_CHDR *tchdr;        /* color map info */
  1585. ULONG *map;        /* used if it's going to be remapped. */
  1586. ULONG map_flag;        /* whether or not to use remap_map info. */
  1587. ULONG imagex,imagey;    /* Size of image buffer. */
  1588. ULONG imaged;        /* Depth of Image. (IFF specific) */
  1589. ULONG *xs,*ys;        /* pos of changed area. */
  1590. ULONG *xe,*ye;        /* size of changed area. */
  1591. ULONG special;        /* Special Info. */
  1592. ULONG extra;        /* extra info needed to decode delta */
  1593. {
  1594.   ULONG r_inc,exitflag,changed,block_cnt;
  1595.   LONG x,y,min_x,max_x,min_y,max_y;
  1596.   UBYTE *dptr;
  1597.   XA_CHDR *chdr;
  1598.   ULONG stream_mode,chrom_mode,chrom_next_uniq;
  1599.   ULONG bhedr,opcode,chrom;
  1600.  
  1601.   stream_mode = ULTI_STREAM0;
  1602.   chrom_mode = ULTI_CHROM_NORM;
  1603.   chrom_next_uniq = FALSE;
  1604.   if (tchdr) {chdr=(tchdr->new_chdr)?(tchdr->new_chdr):(tchdr);} else chdr=0;
  1605.   changed = 0;
  1606.   max_x = max_y = 0;    min_x = imagex;    min_y = imagey;
  1607.   dptr = delta;
  1608.   r_inc = imagex - 4; if (special) r_inc *= 3;
  1609.   x = 0;
  1610.   y = 0;
  1611.   exitflag = 0;
  1612.   block_cnt = ((imagex * imagey) >> 6) + 1;
  1613.   while(!exitflag)
  1614.   { ULONG mask;
  1615.     bhedr = *dptr++;
  1616.  
  1617.     if ( (y > imagey) || (block_cnt < 0) )
  1618.     {
  1619.       exitflag = 1;
  1620.       fprintf(stderr,"y = %ld block_cnt = %ld bhedr = %lx\n",y,block_cnt,bhedr);
  1621.       continue;
  1622.     }
  1623.     else if ( (bhedr & 0xf8) == 0x70) /* ESCAPE */
  1624.     {
  1625.       switch(bhedr)
  1626.       {
  1627.     case 0x70: /* stream mode toggle */ 
  1628.       { ULONG d;
  1629.         d = *dptr++;
  1630.         if (d==0) stream_mode = ULTI_STREAM0;
  1631.         else if (d==1) stream_mode = ULTI_STREAM1;
  1632.         else { fprintf(stderr,"ULTI: stream err %ld\n",stream_mode);
  1633.                TheEnd(); }
  1634.       }
  1635.       break;
  1636.     case 0x71: /* next blk has uniq chrom */
  1637.       chrom_next_uniq = TRUE;
  1638.       break;
  1639.     case 0x72: /* chrom mode toggle */
  1640.       chrom_mode = (chrom_mode==ULTI_CHROM_NORM)?(ULTI_CHROM_UNIQ)
  1641.                             :(ULTI_CHROM_NORM); 
  1642.       break;
  1643.     case 0x73: /* Frame Guard */
  1644.       exitflag = 1; 
  1645.       break;
  1646.     case 0x74: /* Skip */
  1647.       { ULONG cnt = (ULONG)(*dptr++);
  1648.         block_cnt -= cnt;
  1649.         while(cnt--) { x += 8; if (x>=imagex) { x=0; y += 8; } }
  1650.       }
  1651.       break;
  1652.     default: /* reserved escapes */
  1653.       fprintf(stderr,"Reserved Escapes %lx\n",bhedr);
  1654.       exitflag = 1;
  1655.       break;
  1656.       }
  1657.     } /* end of escape */
  1658.     else /* not escape */
  1659.     { ULONG chrom_flag;
  1660.       ULONG quadrant,msh,tx,ty;
  1661.  
  1662.       block_cnt--;
  1663.       if ( (chrom_mode==ULTI_CHROM_UNIQ) || (chrom_next_uniq == TRUE) )
  1664.       { 
  1665.     chrom_next_uniq = FALSE;
  1666.     chrom_flag = TRUE;
  1667.     chrom = 0; 
  1668.       }
  1669.       else 
  1670.       { 
  1671.     chrom_flag = FALSE; 
  1672.     if (bhedr != 0x00) chrom = *dptr++; /* read chrom */
  1673.       }
  1674.       msh = 8; tx = x; ty = y;
  1675.       for(quadrant=0;quadrant<4;quadrant++)
  1676.       { ULONG tx,ty;
  1677.     /* move to quadrant */
  1678.     if (quadrant==0) {tx=x; ty=y;}
  1679.     else if (quadrant==1) ty+=4;
  1680.     else if (quadrant==2) tx+=4;
  1681.     else ty-=4;
  1682.     msh -= 2;
  1683.     opcode = ((bhedr >> msh) & 0x03) | stream_mode;
  1684.  
  1685.         /* POSSIBLY TEST FOR 0x04 or 0x00 1st */
  1686.     switch(opcode)
  1687.     {
  1688.       case 0x04:
  1689.       case 0x00:  /* Unchanged quadrant */
  1690.         /* ??? in unique chrom mode is there a chrom for this quad?? */
  1691.       break;
  1692.  
  1693.       case 0x05:
  1694.       case 0x01:  /* Homogenous/shallow LTC quadrant */
  1695.       {
  1696.         ULONG angle,y0,y1;
  1697.         if (chrom_flag==TRUE) { chrom = *dptr++; }
  1698.         y0 = *dptr++;  angle = (y0 >> 6) & 0x03;  y0 &= 0x3f;
  1699.         if (angle == 0)
  1700.         {
  1701.            AVI_ULTI_LTC(image,tx,ty,imagex,special,map_flag,map,chdr,
  1702.                             y0,y0,y0,y0,chrom,angle);
  1703.         }
  1704.         else
  1705.         {  y1 = y0 + 1; if (y1 > 63) y1 = 63;
  1706.            if (angle==3) angle = 12;
  1707.            else if (angle==2) angle = 6;
  1708.            else (angle==2); 
  1709.            AVI_ULTI_LTC(image,tx,ty,imagex,special,map_flag,map,chdr,
  1710.                          y0,y0,y1,y1,chrom,angle);
  1711.         }
  1712.       }
  1713.       break;
  1714.  
  1715.       case 0x02:  /* LTC quadrant */
  1716.       { ULONG angle,ltc_idx,y0,y1,y2,y3;
  1717.         UBYTE *tmp;
  1718.         if (chrom_flag==TRUE) { chrom = *dptr++; }
  1719.         ltc_idx = (*dptr++) << 8; ltc_idx |= (*dptr++);
  1720.         angle = (ltc_idx >> 12) & 0x0f; /* 4 bits angle */
  1721.         ltc_idx &= 0x0fff; /* index to 4 byte lum table */
  1722.         tmp = &avi_ulti_tab[ ( ltc_idx << 2 ) ];
  1723.         y0 = (ULONG)(*tmp++); y1 = (ULONG)(*tmp++); 
  1724.         y2 = (ULONG)(*tmp++); y3 = (ULONG)(*tmp++);
  1725.         AVI_ULTI_LTC(image,tx,ty,imagex,special,map_flag,map,chdr,
  1726.                     y0,y1,y2,y3,chrom,angle);
  1727.       }
  1728.       break;
  1729.  
  1730.       case 0x03:  /* Statistical/extended LTC */
  1731.       { ULONG d;
  1732.         if (chrom_flag==TRUE) { chrom = *dptr++; }
  1733.         d = *dptr++;
  1734.         if (d & 0x80) /* extend LTC */
  1735.         { ULONG angle,y0,y1,y2,y3;
  1736.           angle = (d >> 4) & 0x07; /* 3 bits angle */
  1737.           d =  (d << 8) | (*dptr++);
  1738.           y0 = (d >> 6) & 0x3f;    y1 = d & 0x3f;
  1739.           y2 = (*dptr++) & 0x3f;   y3 = (*dptr++) & 0x3f;
  1740.           AVI_ULTI_LTC(image,tx,ty,imagex,special,map_flag,map,chdr,
  1741.                          y0,y1,y2,y3,chrom,angle);
  1742.         }
  1743.         else /* Statistical pattern */
  1744.         { ULONG y0,y1; UBYTE flag0,flag1;
  1745.           flag0 = *dptr++;  flag1 = (UBYTE)d;
  1746.           y0 = (*dptr++) & 0x3f;   y1 = (*dptr++) & 0x3f;
  1747.           /* bit 0 => y0, bit 1 = > y1. */
  1748.           /* raster scan order MSB = 0 */
  1749.           if (special)
  1750.           { UBYTE r0,r1,g0,g1,b0,b1;
  1751.         UBYTE *ip = (UBYTE *)(image + 3 * (ty * imagex + tx) );
  1752.             AVI_Get_Ulti_rgbColor(y0,chrom,&r0,&g0,&b0);
  1753.             AVI_Get_Ulti_rgbColor(y1,chrom,&r1,&g1,&b1);
  1754.             AVI_ULTI_rgbC2(ip,flag1,r0,r1,g0,g1,b0,b1,r_inc); 
  1755.         ip += r_inc;
  1756.             AVI_ULTI_rgbC2(ip,flag0,r0,r1,g0,g1,b0,b1,r_inc); 
  1757.           }
  1758.           else 
  1759.           { ULONG c0,c1;
  1760.             c0 = AVI_Get_Ulti_Color(y0,chrom,map_flag,map,chdr);
  1761.             c1 = AVI_Get_Ulti_Color(y1,chrom,map_flag,map,chdr);
  1762.             if ( (x11_bytes_pixel==1) || (map_flag==FALSE) )
  1763.             { UBYTE *ip = (UBYTE *)(image + (ty * imagex + tx) );
  1764.               AVI_ULTI_C2(ip,flag1,UBYTE,c0,c1,r_inc); ip += r_inc;
  1765.               AVI_ULTI_C2(ip,flag0,UBYTE,c0,c1,r_inc);
  1766.         }
  1767.             else if (x11_bytes_pixel==4)
  1768.             { ULONG *ip = (ULONG *)(image + ((ty * imagex + tx)<<2) );
  1769.               AVI_ULTI_C2(ip,flag1,ULONG,c0,c1,r_inc); ip += r_inc;
  1770.               AVI_ULTI_C2(ip,flag0,ULONG,c0,c1,r_inc);
  1771.         }
  1772.             else /* (x11_bytes_pixel==2) */
  1773.             { USHORT *ip = (USHORT *)(image + ((ty * imagex + tx)<<1) );
  1774.               AVI_ULTI_C2(ip,flag1,USHORT,c0,c1,r_inc); ip += r_inc;
  1775.               AVI_ULTI_C2(ip,flag0,USHORT,c0,c1,r_inc);
  1776.         }
  1777.           }
  1778.         }
  1779.       }
  1780.       break;
  1781.  
  1782.       case 0x06:  /* Subsampled 4-luminance quadrant */
  1783.       { ULONG y0,y1,y2,y3;
  1784.         if (chrom_flag==TRUE) { chrom = *dptr++; }
  1785.         y3 = (*dptr++) << 16; y3 |= (*dptr++) << 8; y3 |= (*dptr++);
  1786.         y0 = (y3 >> 18) & 0x3f;  /* NW */
  1787.         y1 = (y3 >> 12) & 0x3f;  /* NE */
  1788.         y2 = (y3 >>  6) & 0x3f;  /* SW */
  1789.         y3 &= 0x3f;   /* SE */
  1790.         AVI_ULTI_LTC(image,tx,ty,imagex,special,map_flag,map,chdr,
  1791.                     y0,y1,y2,y3,chrom,0x10);
  1792.       }
  1793.       break;
  1794.  
  1795.       case 0x07:  /* 16-luminance quadrant */
  1796.       { ULONG i,d,y[16];
  1797.         if (chrom_flag==TRUE) { chrom = *dptr++; }
  1798.         d = (*dptr++) << 16; d |= (*dptr++) << 8; d |= (*dptr++);
  1799.         y[0] = (d >> 18) & 0x3f;   y[1] = (d >> 12) & 0x3f;
  1800.         y[2] = (d >>  6) & 0x3f;   y[3] = d & 0x3f;
  1801.         d = (*dptr++) << 16; d |= (*dptr++) << 8; d |= (*dptr++);
  1802.         y[4] = (d >> 18) & 0x3f;   y[5] = (d >> 12) & 0x3f;
  1803.         y[6] = (d >>  6) & 0x3f;   y[7] = d & 0x3f;
  1804.         d = (*dptr++) << 16; d |= (*dptr++) << 8; d |= (*dptr++);
  1805.         y[8] = (d >> 18) & 0x3f;   y[9] = (d >> 12) & 0x3f;
  1806.         y[10] = (d >>  6) & 0x3f;  y[11] = d & 0x3f;
  1807.         d = (*dptr++) << 16; d |= (*dptr++) << 8; d |= (*dptr++);
  1808.         y[12] = (d >> 18) & 0x3f;  y[13] = (d >> 12) & 0x3f;
  1809.         y[14] = (d >>  6) & 0x3f;  y[15] = d & 0x3f;
  1810.  
  1811.         if (special)
  1812.         { UBYTE r,g,b,*ip = (UBYTE *)(image + 3 * (ty * imagex + tx) );
  1813.           for(i=0;i<16;i++)
  1814.           { AVI_Get_Ulti_rgbColor(y[i],chrom,&r,&g,&b);
  1815.         *ip++ = r; *ip++ = g; *ip++ = b; if ( (i%4)==3) ip += r_inc;
  1816.           }
  1817.         }
  1818.         else if ( (x11_bytes_pixel==1) || (map_flag==FALSE) )
  1819.         { UBYTE c,*ip = (UBYTE *)(image + (ty * imagex + tx) );
  1820.           for(i=0;i<16;i++)
  1821.           { c = (UBYTE)AVI_Get_Ulti_Color(y[i],chrom,map_flag,map,chdr);
  1822.         *ip++ = c; if ( (i%4)==3) ip += r_inc; }
  1823.         }
  1824.         else if (x11_bytes_pixel==4)
  1825.         { ULONG c,*ip = (ULONG *)(image + ((ty * imagex + tx)<<2) );
  1826.           for(i=0;i<16;i++)
  1827.           { c = (ULONG)AVI_Get_Ulti_Color(y[i],chrom,map_flag,map,chdr);
  1828.         *ip++ = c; if ( (i%4)==3) ip += r_inc; }
  1829.         }
  1830.         else /* if (x11_bytes_pixel==2) */
  1831.         { USHORT c,*ip = (USHORT *)(image + ((ty * imagex + tx)<<1) );
  1832.           for(i=0;i<16;i++)
  1833.           { c = (USHORT)AVI_Get_Ulti_Color(y[i],chrom,map_flag,map,chdr);
  1834.         *ip++ = c; if ( (i%4)==3) ip += r_inc; }
  1835.         }
  1836.       }
  1837.       break;
  1838.       default:
  1839.         fprintf(stderr,"Error opcode=%lx\n",opcode);
  1840.         break;
  1841.     } /* end of switch opcode */
  1842.       } /* end of 4 quadrant */
  1843.       { x += 8; if (x>=imagex) { x=0; y += 8; } }
  1844.     } /* end of not escape */
  1845.   } /* end of while */
  1846. changed = 1;
  1847.   { *xs = *ys = 0; *xe = imagex; *ye = imagey; }
  1848.   if (map_flag) return(ACT_DLTA_MAPD);
  1849.   else return(ACT_DLTA_NORM);
  1850. }
  1851.  
  1852.  
  1853. void AVI_ULTI_Gen_YUV()
  1854. {
  1855.   float r0,r1,b0,b1;
  1856.   LONG i;
  1857.  
  1858.   r0 = 16384.0 *  1.40200;
  1859.   b0 = 16384.0 *  1.77200;
  1860.   r1 = 16384.0 * -0.71414;
  1861.   b1 = 16384.0 * -0.34414;
  1862.  
  1863.   for(i=0;i<16;i++)
  1864.   { LONG tmp; float cr,cb;
  1865.     tmp = (i & 0x0f); 
  1866.     cr = 63.0 * ( ((float)(tmp) - 5.0) / 40.0);  
  1867.     cb = 63.0 * ( ((float)(tmp) - 6.0) / 34.0);
  1868.     ulti_Cr[i] = (LONG)(r0 * (float)(cr) );
  1869.     ulti_Cb[i] = (LONG)(b0 * (float)(cb) );
  1870.   }
  1871.   for(i=0;i<256;i++)
  1872.   { LONG tmp; float cr,cb;
  1873.     tmp = (i & 0x0f); 
  1874.     cr = 63.0 * ( ((float)(tmp) - 5.0) / 40.0);  
  1875.     tmp = ( (i>>4) & 0x0f); 
  1876.     cb = 63.0 * ( ((float)(tmp) - 6.0) / 34.0);
  1877.     ulti_CrCb[i] = (LONG)(b1 * cb + r1 * cr); 
  1878.   }
  1879. }
  1880.  
  1881. /*
  1882. > >     y = y6 / 63
  1883. > >     u = (u4 - 5) / 40
  1884. > >     v = (v4 - 6) / 34
  1885.  
  1886. I should have mentioned that these numbers come from inspecting the
  1887. weird decimals used in the specification:
  1888.  
  1889.     2.037 should be 2.032 = 63/31
  1890.  
  1891.     8.226 = 255/31
  1892.  
  1893.     6.375 = 255/40
  1894.  
  1895.     7.5   = 255/34
  1896. */
  1897.  
  1898. void AVI_Get_Ulti_rgbColor(lum,chrom,r,g,b)
  1899. LONG lum;
  1900. ULONG chrom;
  1901. UBYTE *r,*g,*b;
  1902. { ULONG cr,cb,ra,ga,ba;
  1903.   LONG tmp;
  1904.   if (cmap_true_to_gray == TRUE) { ra = ba = ga = lum; }
  1905.   else
  1906.   {
  1907.   lum <<= 14; 
  1908.   cb = (chrom >> 4) & 0x0f;   cr = chrom & 0x0f;
  1909.   tmp = (lum + ulti_Cr[cr]) >> 14; 
  1910.   if (tmp < 0) tmp = 0; else if (tmp > 63) tmp = 63;  ra = tmp;
  1911.   tmp = (lum + ulti_Cb[cb]) >> 14;
  1912.   if (tmp < 0) tmp = 0; else if (tmp > 63) tmp = 63;  ba = tmp;
  1913.   tmp = (lum + ulti_CrCb[chrom]) >> 14;
  1914.   if (tmp < 0) tmp = 0; else if (tmp > 63) tmp = 63;  ga = tmp;
  1915.   }
  1916.   *r = (UBYTE)( (ra << 2) | (ra >> 4) );
  1917.   *g = (UBYTE)( (ga << 2) | (ga >> 4) );
  1918.   *b = (UBYTE)( (ba << 2) | (ba >> 4) );
  1919. }
  1920.  
  1921. ULONG AVI_Get_Ulti_Color(lum,chrom,map_flag,map,chdr)
  1922. LONG lum;        /* 6 bits of lum */
  1923. ULONG chrom;        /* 8 bits of chrom */
  1924. ULONG map_flag,*map;
  1925. XA_CHDR *chdr;
  1926. {
  1927.   register ULONG cr,cb,clr,ra,ga,ba,tr,tg,tb;
  1928.   LONG tmp;
  1929.  
  1930.   if (cmap_true_to_gray == TRUE) { ra = ba = ga = lum; }
  1931.   else
  1932.   { LONG lum1 = lum << 14;
  1933.   cb = (chrom >> 4) & 0x0f;   cr = chrom & 0x0f;
  1934.   tmp = (lum1 + ulti_Cr[cr]) >> 14; 
  1935.   if (tmp < 0) tmp = 0; else if (tmp > 63) tmp = 63;  ra = tmp;
  1936.   tmp = (lum1 + ulti_Cb[cb]) >> 14;
  1937.   if (tmp < 0) tmp = 0; else if (tmp > 63) tmp = 63;  ba = tmp;
  1938.   tmp = (lum1 + ulti_CrCb[chrom]) >> 14;
  1939.   if (tmp < 0) tmp = 0; else if (tmp > 63) tmp = 63;  ga = tmp;
  1940.   }
  1941.  
  1942.   tr = (ra << 2) | (ra >> 4);
  1943.   tg = (ga << 2) | (ga >> 4);
  1944.   tb = (ba << 2) | (ba >> 4);
  1945.   if (xa_gamma_flag==TRUE) { tr = xa_gamma_adj[tr]>>8;  
  1946.      tg = xa_gamma_adj[tg]>>8; tb = xa_gamma_adj[tb]>>8; }
  1947.  
  1948.   if (x11_display_type & XA_X11_TRUE) clr = X11_Get_True_Color(ra,ga,ba,5);
  1949.   else
  1950.   { 
  1951.     if ((cmap_color_func == 4) && (chdr))
  1952.     { register ULONG cache_i = ((lum << 8) | chrom) & 0x3fff;
  1953.       if (cmap_cache == 0) CMAP_Cache_Init();
  1954.       if (chdr != cmap_cache_chdr)
  1955.       {
  1956.     CMAP_Cache_Clear();
  1957.     cmap_cache_chdr = chdr;
  1958.       }
  1959.       if (cmap_cache[cache_i] == 0xffff)
  1960.       {
  1961.         clr = chdr->coff + 
  1962.        CMAP_Find_Closest(chdr->cmap,chdr->csize,ra,ga,ba,6,6,6,TRUE);
  1963.         cmap_cache[cache_i] = (USHORT)clr;
  1964.       }
  1965.       else clr = (ULONG)cmap_cache[cache_i];
  1966.     }
  1967.     else
  1968.     {
  1969.       if (cmap_true_to_332 == TRUE) 
  1970.       clr=CMAP_GET_332(tr,tg,tb,CMAP_SCALE8);
  1971.       else   clr = CMAP_GET_GRAY(tr,tg,tb,CMAP_SCALE13);
  1972.       if (map_flag) clr = map[clr];
  1973.     }
  1974.   }
  1975.   return(clr);
  1976. }
  1977.  
  1978. #define AVI_ULTI_0000(ip,CST,c0,c1,c2,c3,r_inc) { \
  1979.   *ip++ =(CST)c0; *ip++ =(CST)c1; *ip++ =(CST)c2; *ip =(CST)c3; ip += r_inc; \
  1980.   *ip++ =(CST)c0; *ip++ =(CST)c1; *ip++ =(CST)c2; *ip =(CST)c3; ip += r_inc; \
  1981.   *ip++ =(CST)c0; *ip++ =(CST)c1; *ip++ =(CST)c2; *ip =(CST)c3; ip += r_inc; \
  1982.   *ip++ =(CST)c0; *ip++ =(CST)c1; *ip++ =(CST)c2; *ip =(CST)c3; }
  1983.  
  1984. #define AVI_ULTI_0225(ip,CST,c0,c1,c2,c3,r_inc) { \
  1985.   *ip++ =(CST)c1; *ip++ =(CST)c2; *ip++ =(CST)c3; *ip =(CST)c3; ip += r_inc; \
  1986.   *ip++ =(CST)c0; *ip++ =(CST)c1; *ip++ =(CST)c2; *ip =(CST)c3; ip += r_inc; \
  1987.   *ip++ =(CST)c0; *ip++ =(CST)c1; *ip++ =(CST)c2; *ip =(CST)c3; ip += r_inc; \
  1988.   *ip++ =(CST)c0; *ip++ =(CST)c0; *ip++ =(CST)c1; *ip =(CST)c2; }
  1989.  
  1990. #define AVI_ULTI_0450(ip,CST,c0,c1,c2,c3,r_inc) { \
  1991.   *ip++ =(CST)c1; *ip++ =(CST)c2; *ip++ =(CST)c3; *ip =(CST)c3; ip += r_inc; \
  1992.   *ip++ =(CST)c1; *ip++ =(CST)c2; *ip++ =(CST)c2; *ip =(CST)c3; ip += r_inc; \
  1993.   *ip++ =(CST)c0; *ip++ =(CST)c1; *ip++ =(CST)c1; *ip =(CST)c2; ip += r_inc; \
  1994.   *ip++ =(CST)c0; *ip++ =(CST)c0; *ip++ =(CST)c1; *ip =(CST)c2; }
  1995.  
  1996. #define AVI_ULTI_0675(ip,CST,c0,c1,c2,c3,r_inc) { \
  1997.   *ip++ =(CST)c2; *ip++ =(CST)c3; *ip++ =(CST)c3; *ip =(CST)c3; ip += r_inc; \
  1998.   *ip++ =(CST)c1; *ip++ =(CST)c2; *ip++ =(CST)c2; *ip =(CST)c3; ip += r_inc; \
  1999.   *ip++ =(CST)c0; *ip++ =(CST)c1; *ip++ =(CST)c1; *ip =(CST)c2; ip += r_inc; \
  2000.   *ip++ =(CST)c0; *ip++ =(CST)c0; *ip++ =(CST)c0; *ip =(CST)c1; }
  2001.  
  2002. #define AVI_ULTI_0900(ip,CST,c0,c1,c2,c3,r_inc) { \
  2003.   *ip++ =(CST)c3; *ip++ =(CST)c3; *ip++ =(CST)c3; *ip =(CST)c3; ip += r_inc; \
  2004.   *ip++ =(CST)c2; *ip++ =(CST)c2; *ip++ =(CST)c2; *ip =(CST)c2; ip += r_inc; \
  2005.   *ip++ =(CST)c1; *ip++ =(CST)c1; *ip++ =(CST)c1; *ip =(CST)c1; ip += r_inc; \
  2006.   *ip++ =(CST)c0; *ip++ =(CST)c0; *ip++ =(CST)c0; *ip =(CST)c0; }
  2007.  
  2008. #define AVI_ULTI_1125(ip,CST,c0,c1,c2,c3,r_inc) { \
  2009.   *ip++ =(CST)c3; *ip++ =(CST)c3; *ip++ =(CST)c3; *ip =(CST)c2; ip += r_inc; \
  2010.   *ip++ =(CST)c3; *ip++ =(CST)c2; *ip++ =(CST)c2; *ip =(CST)c1; ip += r_inc; \
  2011.   *ip++ =(CST)c2; *ip++ =(CST)c1; *ip++ =(CST)c1; *ip =(CST)c0; ip += r_inc; \
  2012.   *ip++ =(CST)c1; *ip++ =(CST)c0; *ip++ =(CST)c0; *ip =(CST)c0; }
  2013.  
  2014. #define AVI_ULTI_1350(ip,CST,c0,c1,c2,c3,r_inc) { \
  2015.   *ip++ =(CST)c3; *ip++ =(CST)c3; *ip++ =(CST)c2; *ip =(CST)c2; ip += r_inc; \
  2016.   *ip++ =(CST)c3; *ip++ =(CST)c2; *ip++ =(CST)c1; *ip =(CST)c1; ip += r_inc; \
  2017.   *ip++ =(CST)c2; *ip++ =(CST)c2; *ip++ =(CST)c1; *ip =(CST)c0; ip += r_inc; \
  2018.   *ip++ =(CST)c1; *ip++ =(CST)c1; *ip++ =(CST)c0; *ip =(CST)c0; }
  2019.  
  2020. #define AVI_ULTI_1575(ip,CST,c0,c1,c2,c3,r_inc) { \
  2021.   *ip++ =(CST)c3; *ip++ =(CST)c3; *ip++ =(CST)c2; *ip =(CST)c1; ip += r_inc; \
  2022.   *ip++ =(CST)c3; *ip++ =(CST)c2; *ip++ =(CST)c1; *ip =(CST)c0; ip += r_inc; \
  2023.   *ip++ =(CST)c3; *ip++ =(CST)c2; *ip++ =(CST)c1; *ip =(CST)c0; ip += r_inc; \
  2024.   *ip++ =(CST)c2; *ip++ =(CST)c1; *ip++ =(CST)c0; *ip =(CST)c0; }
  2025.  
  2026. #define AVI_ULTI_C4(ip,CST,c0,c1,c2,c3,r_inc) { \
  2027.   *ip++ =(CST)c0; *ip++ =(CST)c0; *ip++ =(CST)c1; *ip =(CST)c1; ip += r_inc; \
  2028.   *ip++ =(CST)c0; *ip++ =(CST)c0; *ip++ =(CST)c1; *ip =(CST)c1; ip += r_inc; \
  2029.   *ip++ =(CST)c2; *ip++ =(CST)c2; *ip++ =(CST)c3; *ip =(CST)c3; ip += r_inc; \
  2030.   *ip++ =(CST)c2; *ip++ =(CST)c2; *ip++ =(CST)c3; *ip =(CST)c3; }
  2031.  
  2032. void AVI_ULTI_LTC(image,x,y,imagex,special,map_flag,map,chdr,
  2033.                     y0,y1,y2,y3,chrom,angle)
  2034. UBYTE *image;
  2035. ULONG x,y,imagex,special,map_flag,*map;
  2036. XA_CHDR *chdr;
  2037. ULONG y0,y1,y2,y3,chrom,angle;
  2038. { ULONG r_inc;
  2039.  
  2040.   if (special)
  2041.   { ULONG i;
  2042.     UBYTE *ip = (UBYTE *)(image + 3 * (y * imagex + x) );
  2043.     UBYTE r[4],g[4],b[4],*ix,idx[16];
  2044.     r_inc = 3 * (imagex - 4);
  2045.     if (angle & 0x08) /* reverse */
  2046.     { angle &= 0x07;
  2047.       AVI_Get_Ulti_rgbColor(y3,chrom,&r[0],&g[0],&b[0]);
  2048.       AVI_Get_Ulti_rgbColor(y2,chrom,&r[1],&g[1],&b[1]);
  2049.       AVI_Get_Ulti_rgbColor(y1,chrom,&r[2],&g[2],&b[2]);
  2050.       AVI_Get_Ulti_rgbColor(y0,chrom,&r[3],&g[3],&b[3]);
  2051.     }
  2052.     else
  2053.     {
  2054.       AVI_Get_Ulti_rgbColor(y0,chrom,&r[0],&g[0],&b[0]);
  2055.       if (y1==y0) {r[1]=r[0]; g[1]=g[0]; b[1]=b[0]; }
  2056.       else AVI_Get_Ulti_rgbColor(y1,chrom,&r[1],&g[1],&b[1]);
  2057.       if (y2==y1) {r[2]=r[1]; g[2]=g[1]; b[2]=b[1]; }
  2058.       else AVI_Get_Ulti_rgbColor(y2,chrom,&r[2],&g[2],&b[2]);
  2059.       if (y3==y2) {r[3]=r[2]; g[3]=g[2]; b[3]=b[2]; }
  2060.       else AVI_Get_Ulti_rgbColor(y3,chrom,&r[3],&g[3],&b[3]);
  2061.     }
  2062.     ix = idx;
  2063.     switch(angle)
  2064.     {   case 0: AVI_ULTI_0000(ix,UBYTE,0,1,2,3,1); break;
  2065.     case 1: AVI_ULTI_0225(ix,UBYTE,0,1,2,3,1); break;
  2066.     case 2: AVI_ULTI_0450(ix,UBYTE,0,1,2,3,1); break;
  2067.     case 3: AVI_ULTI_0675(ix,UBYTE,0,1,2,3,1); break;
  2068.     case 4: AVI_ULTI_0900(ix,UBYTE,0,1,2,3,1); break;
  2069.     case 5: AVI_ULTI_1125(ix,UBYTE,0,1,2,3,1); break;
  2070.     case 6: AVI_ULTI_1350(ix,UBYTE,0,1,2,3,1); break;
  2071.     case 7: AVI_ULTI_1575(ix,UBYTE,0,1,2,3,1); break;
  2072.     default: AVI_ULTI_C4(ix,UBYTE,0,1,2,3,1); break;
  2073.     } /* end switch */
  2074.     for(i=0;i<16;i++)
  2075.     { register ULONG j = idx[i];
  2076.       *ip++ = r[j]; *ip++ = g[j]; *ip++ = b[j];
  2077.       if ( (i & 3) == 3 ) ip += r_inc;
  2078.     }
  2079.   }
  2080.   else 
  2081.   { ULONG c0,c1,c2,c3;
  2082.     r_inc = imagex - 3;
  2083.     if (angle & 0x08) /* reverse */
  2084.     { angle &= 0x07;
  2085.       c0 = AVI_Get_Ulti_Color(y3,chrom,map_flag,map,chdr);
  2086.       c1 = AVI_Get_Ulti_Color(y2,chrom,map_flag,map,chdr);
  2087.       c2 = AVI_Get_Ulti_Color(y1,chrom,map_flag,map,chdr);
  2088.       c3 = AVI_Get_Ulti_Color(y0,chrom,map_flag,map,chdr);
  2089.     }
  2090.     else
  2091.     {
  2092.       c0 = AVI_Get_Ulti_Color(y0,chrom,map_flag,map,chdr);
  2093.       if (y1==y0) c1 = c0;
  2094.       else c1 = AVI_Get_Ulti_Color(y1,chrom,map_flag,map,chdr);
  2095.       if (y2==y1) c2 = c1;
  2096.       else c2 = AVI_Get_Ulti_Color(y2,chrom,map_flag,map,chdr);
  2097.       if (y3==y2) c3 = c2;
  2098.       else c3 = AVI_Get_Ulti_Color(y3,chrom,map_flag,map,chdr);
  2099.     }
  2100.  
  2101.     if ( (x11_bytes_pixel == 1) || (map_flag == FALSE) )
  2102.     { UBYTE *ip = (UBYTE *)(image + (y * imagex + x) );
  2103.       switch(angle)
  2104.       { case 0: AVI_ULTI_0000(ip,UBYTE,c0,c1,c2,c3,r_inc); break;
  2105.     case 1: AVI_ULTI_0225(ip,UBYTE,c0,c1,c2,c3,r_inc); break;
  2106.     case 2: AVI_ULTI_0450(ip,UBYTE,c0,c1,c2,c3,r_inc); break;
  2107.     case 3: AVI_ULTI_0675(ip,UBYTE,c0,c1,c2,c3,r_inc); break;
  2108.     case 4: AVI_ULTI_0900(ip,UBYTE,c0,c1,c2,c3,r_inc); break;
  2109.     case 5: AVI_ULTI_1125(ip,UBYTE,c0,c1,c2,c3,r_inc); break;
  2110.     case 6: AVI_ULTI_1350(ip,UBYTE,c0,c1,c2,c3,r_inc); break;
  2111.     case 7: AVI_ULTI_1575(ip,UBYTE,c0,c1,c2,c3,r_inc); break;
  2112.     default: AVI_ULTI_C4(ip,UBYTE,c0,c1,c2,c3,r_inc); break;
  2113.       }
  2114.     }
  2115.     else if (x11_bytes_pixel == 4)
  2116.     { ULONG *ip = (ULONG *)(image + ((y * imagex + x) << 2) );
  2117.       switch(angle)
  2118.       { case 0: AVI_ULTI_0000(ip,ULONG,c0,c1,c2,c3,r_inc); break;
  2119.     case 1: AVI_ULTI_0225(ip,ULONG,c0,c1,c2,c3,r_inc); break;
  2120.     case 2: AVI_ULTI_0450(ip,ULONG,c0,c1,c2,c3,r_inc); break;
  2121.     case 3: AVI_ULTI_0675(ip,ULONG,c0,c1,c2,c3,r_inc); break;
  2122.     case 4: AVI_ULTI_0900(ip,ULONG,c0,c1,c2,c3,r_inc); break;
  2123.     case 5: AVI_ULTI_1125(ip,ULONG,c0,c1,c2,c3,r_inc); break;
  2124.     case 6: AVI_ULTI_1350(ip,ULONG,c0,c1,c2,c3,r_inc); break;
  2125.     case 7: AVI_ULTI_1575(ip,ULONG,c0,c1,c2,c3,r_inc); break;
  2126.     default: AVI_ULTI_C4(ip,ULONG,c0,c1,c2,c3,r_inc); break;
  2127.       }
  2128.     }
  2129.     else /* if (x11_bytes_pixel == 1) */
  2130.     { USHORT *ip = (USHORT *)(image + ( (y * imagex + x) << 1) );
  2131.       switch(angle)
  2132.       { case 0: AVI_ULTI_0000(ip,USHORT,c0,c1,c2,c3,r_inc); break;
  2133.     case 1: AVI_ULTI_0225(ip,USHORT,c0,c1,c2,c3,r_inc); break;
  2134.     case 2: AVI_ULTI_0450(ip,USHORT,c0,c1,c2,c3,r_inc); break;
  2135.     case 3: AVI_ULTI_0675(ip,USHORT,c0,c1,c2,c3,r_inc); break;
  2136.     case 4: AVI_ULTI_0900(ip,USHORT,c0,c1,c2,c3,r_inc); break;
  2137.     case 5: AVI_ULTI_1125(ip,USHORT,c0,c1,c2,c3,r_inc); break;
  2138.     case 6: AVI_ULTI_1350(ip,USHORT,c0,c1,c2,c3,r_inc); break;
  2139.     case 7: AVI_ULTI_1575(ip,USHORT,c0,c1,c2,c3,r_inc); break;
  2140.     default: AVI_ULTI_C4(ip,USHORT,c0,c1,c2,c3,r_inc); break;
  2141.       }
  2142.     } /* end of shorts */
  2143.   } /* end of not special */
  2144. } /* end */
  2145.  
  2146.  
  2147. ULONG RIFF_Read_AUDS(fin,size,auds_hdr)
  2148. FILE *fin;
  2149. LONG size;
  2150. AUDS_HDR *auds_hdr;
  2151. { ULONG ret = TRUE;
  2152.   auds_hdr->format    = UTIL_Get_LSB_Short(fin);
  2153.   auds_hdr->channels    = UTIL_Get_LSB_Short(fin);
  2154.   auds_hdr->rate    = UTIL_Get_LSB_Long(fin);
  2155.   auds_hdr->av_bps    = UTIL_Get_LSB_Long(fin);
  2156.   auds_hdr->align    = UTIL_Get_MSB_Short(fin);
  2157.   auds_hdr->size    = UTIL_Get_LSB_Short(fin);
  2158.  
  2159.   DEBUG_LEVEL2 fprintf(stderr,"ret = %lx\n",ret);
  2160.   if (auds_hdr->format == WAVE_FORMAT_PCM)
  2161.   {
  2162.     if (auds_hdr->size == 8) avi_audio_type = XA_AUDIO_LINEAR;
  2163.     else if (auds_hdr->size == 16) avi_audio_type = XA_AUDIO_SIGNED;
  2164.     else avi_audio_type = XA_AUDIO_INVALID;
  2165.   }
  2166.   else if (auds_hdr->format == WAVE_FORMAT_ADPCM)
  2167.   {
  2168.     if (auds_hdr->size == 4) avi_audio_type = XA_AUDIO_ADPCM;
  2169.     else avi_audio_type = XA_AUDIO_INVALID;
  2170.   }
  2171.   else
  2172.   {
  2173.     avi_audio_type = XA_AUDIO_INVALID;
  2174.     ret = FALSE;
  2175.   }
  2176.   avi_audio_freq  = auds_hdr->rate;
  2177.   avi_audio_chans = auds_hdr->channels;
  2178.   if (auds_hdr->size == 8) avi_audio_bps = 1;
  2179.   else if (auds_hdr->size == 16) avi_audio_bps = 2;
  2180.   else if (auds_hdr->size == 32) avi_audio_bps = 4;
  2181.   else if (auds_hdr->size == 4) avi_audio_bps = 1;
  2182.   else avi_audio_bps = 1000 + auds_hdr->size;
  2183.   avi_audio_end   = 0;
  2184.   if (avi_audio_chans > 2) ret = FALSE;
  2185.   if (avi_audio_bps > 2) ret = FALSE;
  2186.  
  2187. #ifdef POD_AUDIO_BETA
  2188.   if (xa_verbose)
  2189.   {
  2190.     fprintf(stderr,"  Audio: "); AVI_Audio_Type(auds_hdr->format);
  2191.     fprintf(stderr," Rate %ld Chans %ld bps %ld\n",
  2192.             avi_audio_freq,avi_audio_chans,auds_hdr->size);
  2193.   }
  2194. #endif
  2195. /* modify type */
  2196.   if (avi_audio_chans==2)    avi_audio_type |= XA_AUDIO_STEREO_MSK;
  2197.   if (avi_audio_bps==2)        avi_audio_type |= XA_AUDIO_BPS_2_MSK;
  2198.   DEBUG_LEVEL2 fprintf(stderr,"ret = %lx\n",ret);
  2199.   if (size & 01) size++; size -= 16;
  2200.   while(size--) fgetc(fin);
  2201.   return(ret);
  2202. }
  2203.  
  2204. void AVI_Audio_Type(type)
  2205. ULONG type;
  2206. {
  2207.   switch(type)
  2208.   {
  2209.     case WAVE_FORMAT_PCM: fprintf(stderr,"PCM"); break;
  2210.     case WAVE_FORMAT_ADPCM: fprintf(stderr,"ADPCM"); break;
  2211.     case WAVE_FORMAT_ALAW: fprintf(stderr,"ALAW"); break;
  2212.     case WAVE_FORMAT_MULAW: fprintf(stderr,"ULAW"); break;
  2213.     case WAVE_FORMAT_OKI_ADPCM: fprintf(stderr,"OKI_ADPCM"); break;
  2214.     case IBM_FORMAT_MULAW: fprintf(stderr,"IBM_ULAW"); break;
  2215.     case IBM_FORMAT_ALAW: fprintf(stderr,"IBM_ALAW"); break;
  2216.     case IBM_FORMAT_ADPCM: fprintf(stderr,"IBM_ADPCM"); break;
  2217.     default: fprintf(stderr,"UNK%lx",type); break;
  2218.   }
  2219. }
  2220.  
  2221. static UBYTE avi_ulti_lin[11] = {2,3,5,6,7,8,11,14,17,20,255};
  2222. static UBYTE avi_ulti_lo[15]  = {4,5,6,7,8,11,14,17,20,23,26,29,32,36,255};
  2223. static UBYTE avi_ulti_hi[14]  = {6,8,11,14,17,20,23,26,29,32,35,40,46,255};
  2224.  
  2225. ULONG AVI_Ulti_Check(val,ptr)
  2226. ULONG val;
  2227. UBYTE *ptr;
  2228.   while(*ptr != 255) if ((ULONG)(*ptr++) == val) return(1);
  2229.   return(0);
  2230. }
  2231.  
  2232. void AVI_Ulti_Gen_LTC()
  2233. { LONG ys,ye,ydelta;
  2234.   UBYTE *utab;
  2235.   if (avi_ulti_tab==0) avi_ulti_tab = (UBYTE *)malloc(16384 * sizeof(UBYTE));
  2236.   else return;
  2237.   if (avi_ulti_tab==0) TheEnd1("AVI_Ulti_Gen_LTC: malloc err");
  2238.   utab = avi_ulti_tab;
  2239.   for(ys=0; ys <= 63; ys++)
  2240.   {
  2241.     for(ye=ys; ye <= 63; ye++)
  2242.     {
  2243.       ydelta = ye - ys;
  2244.       if (AVI_Ulti_Check(ydelta,avi_ulti_lin))
  2245.     { ULONG yinc = (ydelta + 1) / 3;
  2246.       *utab++ = ys; *utab++ = ys + yinc; *utab++ = ye - yinc; *utab++ = ye;
  2247.     }
  2248.       if (AVI_Ulti_Check(ydelta,avi_ulti_lo)==1)
  2249.     { LONG y1,y2;
  2250.           float yd = (float)(ydelta);
  2251.       /* 1/4 */
  2252.       y1 = ye - (LONG)(  (2 * yd - 5.0) / 10.0 );
  2253.       y2 = ye - (LONG)(  (    yd - 5.0) / 10.0 );
  2254.       *utab++ = ys; *utab++ = y1; *utab++ = y2; *utab++ = ye;
  2255.       /* 1/2 */
  2256.       y2 = ys + (LONG)(  (2 * yd + 5.0) / 10.0 );
  2257.       *utab++ = ys; *utab++ = y2; *utab++ = y1; *utab++ = ye;
  2258.       /* 3/4 */
  2259.       y1 = ys + (LONG)(  (    yd + 5.0) / 10.0 );
  2260.       *utab++ = ys; *utab++ = y1; *utab++ = y2; *utab++ = ye;
  2261.     }
  2262.       if (AVI_Ulti_Check(ydelta,avi_ulti_hi)==1)
  2263.     {
  2264.       *utab++ = ys; *utab++ = ye; *utab++ = ye; *utab++ = ye;
  2265.       *utab++ = ys; *utab++ = ys; *utab++ = ye; *utab++ = ye;
  2266.       *utab++ = ys; *utab++ = ys; *utab++ = ys; *utab++ = ye;
  2267.     }
  2268.     }
  2269.   }
  2270. DEBUG_LEVEL1
  2271. { ULONG i;
  2272.   UBYTE *tmp = avi_ulti_tab;
  2273.   for(i=0;i<4096;i++)
  2274.   {
  2275.     fprintf(stderr,"%02lx %02lx %02lx %02lx\n",tmp[0],tmp[1],tmp[2],tmp[3]);
  2276.     tmp += 4;
  2277.   }
  2278. }
  2279. }
  2280.  
  2281.  
  2282.